diff --git a/dbus-top/.clang-format b/dbus-top/.clang-format
new file mode 100644
index 0000000..3652c56
--- /dev/null
+++ b/dbus-top/.clang-format
@@ -0,0 +1,113 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterCaseLabel:  true
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  AfterExternBlock: true
+  BeforeCatch:     true
+  BeforeElse:      true
+  IndentBraces:    false
+  SplitEmptyFunction:   false
+  SplitEmptyRecord:     false
+  SplitEmptyNamespace:  false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+BreakInheritanceList: AfterColon
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+PointerAlignment: Left
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeBlocks: Regroup
+IncludeCategories:
+  - Regex:           '^[<"](gtest|gmock)'
+    Priority:        7
+  - Regex:           '^"config.h"'
+    Priority:        -1
+  - Regex:           '^".*\.h"'
+    Priority:        1
+  - Regex:           '^".*\.hpp"'
+    Priority:        2
+  - Regex:           '^<.*\.h>'
+    Priority:        3
+  - Regex:           '^<.*\.hpp>'
+    Priority:        4
+  - Regex:           '^<.*'
+    Priority:        5
+  - Regex:           '.*'
+    Priority:        6
+IndentCaseLabels: true
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Latest
+TabWidth:        4
+UseTab:          Never
diff --git a/dbus-top/.gitignore b/dbus-top/.gitignore
new file mode 100644
index 0000000..a2ae220
--- /dev/null
+++ b/dbus-top/.gitignore
@@ -0,0 +1,3 @@
+oe-logs
+oe-workdir
+.vscode
diff --git a/dbus-top/.vscode/settings.json b/dbus-top/.vscode/settings.json
new file mode 100644
index 0000000..dc4386f
--- /dev/null
+++ b/dbus-top/.vscode/settings.json
@@ -0,0 +1,13 @@
+{
+    "C_Cpp.errorSquiggles": "Disabled",
+    "files.associations": {
+        "filesystem": "cpp",
+        "*.ipp": "cpp",
+<<<<<<< HEAD
+        "iosfwd": "cpp",
+        "thread": "cpp"
+=======
+        "iosfwd": "cpp"
+>>>>>>> cf7590f (Revert "dbus-top: WIP of all currently-implemented features")
+    }
+}
\ No newline at end of file
diff --git a/dbus-top/analyzer.cpp b/dbus-top/analyzer.cpp
new file mode 100644
index 0000000..f31868c
--- /dev/null
+++ b/dbus-top/analyzer.cpp
@@ -0,0 +1,624 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "analyzer.hpp"
+#include "histogram.hpp"
+#include "main.hpp"
+#include "sensorhelper.hpp"
+#include "views.hpp"
+#include "xmlparse.hpp"
+
+#include <unistd.h>
+#include <atomic>
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+extern SensorSnapshot* g_sensor_snapshot;
+extern DBusConnectionSnapshot* g_connection_snapshot;
+extern sd_bus* g_bus;
+extern SensorDetailView* g_sensor_detail_view;
+
+static std::unordered_map<uint64_t, uint64_t>
+    in_flight_methodcalls; // serial => microseconds
+uint64_t Microseconds()
+{
+    long us;  // usec
+    time_t s; // Seconds
+    struct timespec spec;
+    clock_gettime(CLOCK_REALTIME, &spec);
+    s = spec.tv_sec;
+    us = round(spec.tv_nsec / 1000); // Convert nanoseconds to milliseconds
+    if (us > 999999)
+    {
+        s++;
+        us = 0;
+    }
+    return s * 1000000 + us;
+}
+
+int g_update_interval_millises = 2000;
+int GetSummaryIntervalInMillises()
+{
+    return g_update_interval_millises;
+}
+
+bool DBusTopSortFieldIsNumeric(DBusTopSortField field)
+{
+    switch (field)
+    {
+        case kSender:
+        case kDestination:
+        case kInterface:
+        case kPath:
+        case kMember:
+        case kSenderCMD:
+            return false;
+        case kSenderPID:
+        case kMsgPerSec:
+        case kAverageLatency:
+            return true;
+    }
+    return false;
+}
+
+namespace dbus_top_analyzer
+{
+    DBusTopStatistics g_dbus_statistics;
+    Histogram<float> g_mc_time_histogram;
+    std::unordered_map<uint32_t, uint64_t> in_flight_methodcalls;
+    std::atomic<bool> g_program_done = false;
+    std::chrono::time_point<std::chrono::steady_clock> g_last_update;
+    DBusTopStatisticsCallback g_callback;
+    void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb)
+    {
+        g_callback = cb;
+    }
+
+    int UserInputThread()
+    {
+        return 0;
+    }
+
+    std::string g_dbus_top_conn = " ";
+    void SetDBusTopConnectionForMonitoring(const std::string& conn)
+    {
+        g_dbus_top_conn = conn;
+    }
+
+    // Performs one step of analysis
+    void Process()
+    {
+        std::chrono::time_point<std::chrono::steady_clock> t =
+            std::chrono::steady_clock::now();
+        std::chrono::time_point<std::chrono::steady_clock> next_update =
+            g_last_update + std::chrono::milliseconds(g_update_interval_millises);
+        if (t >= next_update)
+        {
+            float seconds_since_last_sample =
+                std::chrono::duration_cast<std::chrono::microseconds>(t -
+                                                                    g_last_update)
+                    .count() /
+                1000000.0f;
+            g_dbus_statistics.seconds_since_last_sample_ =
+                seconds_since_last_sample;
+            // Update snapshot
+            if (g_callback)
+            {
+                g_callback(&g_dbus_statistics, &g_mc_time_histogram);
+            }
+            g_dbus_statistics.Reset();
+            g_last_update = t;
+        }
+    }
+
+    void Finish()
+    {
+        g_program_done = true;
+    }
+
+    std::vector<std::string> FindAllObjectPathsForService(
+        const std::string& service,
+        std::function<void(const std::string&, const std::vector<std::string>&)>
+            on_interface_cb)
+    {
+        sd_bus_error err = SD_BUS_ERROR_NULL;
+        sd_bus_message *m, *reply;
+        std::vector<std::string> paths; // Current iteration
+        std::vector<std::string>
+            all_obj_paths; // All object paths under the supervision of ObjectMapper
+        paths.push_back("/");
+        // busctl call xyz.openbmc_project.ObjectMapper        /
+        // org.freedesktop.DBus.Introspectable        Introspect
+        while (!paths.empty())
+        {
+            // printf("%d paths to explore, total %d paths so far\n",
+            // int(paths.size()), int(all_obj_paths.size()));
+            std::vector<std::string> new_paths;
+            for (const std::string& obj_path : paths)
+            {
+                all_obj_paths.push_back(obj_path);
+                int r = sd_bus_message_new_method_call(
+                    g_bus, &m, service.c_str(), obj_path.c_str(),
+                    "org.freedesktop.DBus.Introspectable", "Introspect");
+                if (r < 0)
+                {
+                    printf("Oh! Cannot create new method call. r=%d, strerror=%s\n",
+                        r, strerror(-r));
+                    continue;
+                }
+                r = sd_bus_call(g_bus, m, 0, &err, &reply);
+                if (r < 0)
+                {
+                    printf("Could not execute method call, r=%d, strerror=%s\n", r,
+                        strerror(-r));
+                }
+                const char* sig = sd_bus_message_get_signature(reply, 0);
+                if (!strcmp(sig, "s"))
+                {
+                    const char* s;
+                    int r = sd_bus_message_read(reply, "s", &s);
+                    std::string s1(s);
+                    if (r < 0)
+                    {
+                        printf("Could not read string payload, r=%d, strerror=%s\n",
+                            r, strerror(-r));
+                    }
+                    else
+                    {
+                        XMLNode* t = ParseXML(s1);
+                        std::vector<std::string> ch = t->GetChildNodeNames();
+                        if (on_interface_cb != nullptr)
+                        {
+                            on_interface_cb(obj_path, t->GetInterfaceNames());
+                        }
+                        DeleteTree(t);
+                        for (const std::string& cn : ch)
+                        {
+                            std::string ch_path = obj_path;
+                            if (obj_path.back() == '/')
+                            {}
+                            else
+                                ch_path.push_back('/');
+                            ch_path += cn;
+                            new_paths.push_back(ch_path);
+                        }
+                    }
+                }
+            }
+            paths = new_paths;
+        }
+        return all_obj_paths;
+    }
+
+    void ListAllSensors()
+    {
+        g_connection_snapshot = new DBusConnectionSnapshot();
+        printf("1. Getting names\n");
+        char** names;
+        int r = sd_bus_list_names(g_bus, &names, nullptr);
+        std::vector<std::string> services;
+        std::vector<int> pids;
+        std::vector<std::string> comms;
+        for (char** ptr = names; ptr && *ptr; ++ptr)
+        {
+            services.push_back(*ptr);
+            free(*ptr);
+        }
+        free(names);
+        printf("2. Getting creds of each name\n");
+        for (int i = 0; i < static_cast<int>(services.size()); i++)
+        {
+            const std::string& service = services[i];
+            sd_bus_creds* creds = nullptr;
+            r = sd_bus_get_name_creds(g_bus, services[i].c_str(),
+                                    SD_BUS_CREDS_AUGMENT | SD_BUS_CREDS_EUID |
+                                        SD_BUS_CREDS_PID | SD_BUS_CREDS_COMM |
+                                        SD_BUS_CREDS_UNIQUE_NAME |
+                                        SD_BUS_CREDS_UNIT | SD_BUS_CREDS_SESSION |
+                                        SD_BUS_CREDS_DESCRIPTION,
+                                    &creds);
+            // PID
+            int pid = INVALID;
+            if (r < 0)
+            {
+                printf("Oh! Cannot get creds for %s\n", services[i].c_str());
+            }
+            else
+            {
+                r = sd_bus_creds_get_pid(creds, &pid);
+            }
+            pids.push_back(pid);
+            // comm
+            std::string comm;
+            if (pid != INVALID)
+            {
+                std::ifstream ifs("/proc/" + std::to_string(pid) + "/cmdline");
+                std::string line;
+                std::getline(ifs, line);
+                for (char c : line)
+                {
+                    if (c < 32 || c >= 127)
+                        c = ' ';
+                    comm.push_back(c);
+                }
+            }
+            comms.push_back(comm);
+            // unique name, also known as "Connection"
+            std::string connection;
+            const char* u;
+            r = sd_bus_creds_get_unique_name(creds, &u);
+            if (r >= 0)
+            {
+                connection = u;
+            }
+            else
+            {
+                printf("Oh! Could not get unique name for %s\n", service.c_str());
+            }
+            std::string unit;
+            r = sd_bus_creds_get_unit(creds, &u);
+            if (r >= 0)
+            {
+                unit = u;
+            }
+            else
+            {
+                printf("Oh! Could not get unit name for %s\n", unit.c_str());
+            }
+            printf("AddConnection    %s    %s    %s    %s    %d\n", service.c_str(),
+                connection.c_str(), comm.c_str(), unit.c_str(), pid);
+            g_connection_snapshot->AddConnection(service, connection, comm, unit,
+                                                pid);
+        }
+        printf("There are %d DBus names.\n", int(services.size()));
+        for (int i = 0; i < int(services.size()); i++)
+        {
+            printf("    %d: %s [%s]\n", i, services[i].c_str(), comms[i].c_str());
+        }
+        g_sensor_snapshot = new SensorSnapshot(g_connection_snapshot);
+        // busctl call xyz.openbmc_project.ObjectMapper /
+        // org.freedesktop.DBus.Introspectable Introspect
+        printf("3. See which sensors are visible from Object Mapper\n");
+        printf("3.1. Introspect Object Mapper for object paths\n");
+        std::vector<std::string> all_obj_paths = FindAllObjectPathsForService(
+            "xyz.openbmc_project.ObjectMapper", nullptr);
+        sd_bus_error err = SD_BUS_ERROR_NULL;
+        sd_bus_message *m, *reply;
+        printf("%d paths found while introspecting ObjectMapper.\n",
+            int(all_obj_paths.size()));
+        printf("3.2. Call ObjectMapper's GetObject method against the sensor "
+            "object paths that represent sensors\n");
+        for (const std::string& p : all_obj_paths)
+        {
+            if (IsSensorObjectPath(p))
+            {
+                err = SD_BUS_ERROR_NULL;
+                r = sd_bus_message_new_method_call(
+                    g_bus, &m, "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetObject");
+                if (r < 0)
+                {
+                    printf("Cannot create new method call. r=%d, strerror=%s\n", r,
+                        strerror(-r));
+                    continue;
+                }
+                r = sd_bus_message_append_basic(m, 's', p.c_str());
+                if (r < 0)
+                {
+                    printf("Could not append a string parameter to m\n");
+                    continue;
+                }
+                // empty array
+                r = sd_bus_message_open_container(m, 'a', "s");
+                if (r < 0)
+                {
+                    printf("Could not open a container for m\n");
+                    continue;
+                }
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                {
+                    printf("Could not close container for m\n");
+                    continue;
+                }
+                r = sd_bus_call(g_bus, m, 0, &err, &reply);
+                if (r < 0)
+                {
+                    printf("Error performing dbus method call\n");
+                }
+                const char* sig = sd_bus_message_get_signature(reply, 0);
+                if (!strcmp(sig, "a{sas}"))
+                {
+                    r = sd_bus_message_enter_container(reply, 'a', "{sas}");
+                    if (r < 0)
+                    {
+                        printf("Could not enter the level 0 array container\n");
+                        continue;
+                    }
+                    while (true)
+                    {
+                        r = sd_bus_message_enter_container(
+                            reply, SD_BUS_TYPE_DICT_ENTRY, "sas");
+                        if (r < 0)
+                        {
+                            // printf("Could not enter the level 1 dict
+                            // container\n");
+                            goto DONE;
+                        }
+                        else if (r == 0)
+                        {}
+                        else
+                        {
+                            // The following 2 correspond to `interface_map` in
+                            // phosphor-mapper
+                            const char* interface_map_first;
+                            r = sd_bus_message_read_basic(reply, 's',
+                                                        &interface_map_first);
+                            if (r < 0)
+                            {
+                                printf("Could not read interface_map_first\n");
+                                goto DONE;
+                            }
+                            r = sd_bus_message_enter_container(reply, 'a', "s");
+                            if (r < 0)
+                            {
+                                printf("Could not enter the level 2 array "
+                                    "container\n");
+                                goto DONE;
+                            }
+                            bool has_value_interface = false;
+                            while (true)
+                            {
+                                const char* interface_map_second;
+                                r = sd_bus_message_read_basic(
+                                    reply, 's', &interface_map_second);
+                                if (r < 0)
+                                {
+                                    printf("Could not read interface_map_second\n");
+                                }
+                                else if (r == 0)
+                                    break;
+                                else
+                                {
+                                    // printf("    %s\n", interface_map_second);
+                                    if (!strcmp(interface_map_second,
+                                                "xyz.openbmc_project.Sensor.Value"))
+                                    {
+                                        has_value_interface = true;
+                                    }
+                                }
+                            }
+                            if (has_value_interface)
+                            {
+                                g_sensor_snapshot->SerSensorVisibleFromObjectMapper(
+                                    std::string(interface_map_first), p);
+                            }
+                            r = sd_bus_message_exit_container(reply);
+                        }
+                        r = sd_bus_message_exit_container(reply);
+                    }
+                    r = sd_bus_message_exit_container(reply);
+                }
+            DONE:
+            {}
+            }
+        }
+        printf("4. Check Hwmon's DBus objects\n");
+        for (int i = 0; i < int(comms.size()); i++)
+        {
+            const std::string& comm = comms[i];
+            const std::string& service = services[i];
+            if (comm.find("phosphor-hwmon-readd") != std::string::npos &&
+                !IsUniqueName(service))
+            {
+                // printf("Should introspect %s\n", service.c_str());
+                std::vector<std::string> objpaths =
+                    FindAllObjectPathsForService(service, nullptr);
+                for (const std::string& op : objpaths)
+                {
+                    if (IsSensorObjectPath(op))
+                    {
+                        g_sensor_snapshot->SetSensorVisibleFromHwmon(service, op);
+                    }
+                }
+            }
+        }
+        // Call `ipmitool sdr list` and see which sensors exist.
+        printf("5. Checking ipmitool SDR List\n");
+        std::string out;
+        bool skip_sdr_list = false;
+        if (getenv("SKIP"))
+        {
+            skip_sdr_list = true;
+        }
+        if (!skip_sdr_list)
+        {
+            constexpr int MAX_BUFFER = 255;
+            char buffer[MAX_BUFFER];
+            FILE* stream = popen("ipmitool sdr list", "r");
+            while (fgets(buffer, MAX_BUFFER, stream) != NULL)
+            {
+                out.append(buffer);
+            }
+            pclose(stream);
+        }
+        std::stringstream ss(out);
+        while (true)
+        {
+            std::string sensor_id, reading, status;
+            std::getline(ss, sensor_id, '|');
+            std::getline(ss, reading, '|');
+            std::getline(ss, status);
+            // printf("%s %s %s\n", sensor_id.c_str(), reading.c_str(),
+            // status.c_str());
+            if (sensor_id.size() > 0 && reading.size() > 0 && status.size() > 0)
+            {
+                g_sensor_snapshot->SetSensorVisibleFromIpmitoolSdr(Trim(sensor_id));
+            }
+            else
+                break;
+        }
+        printf("=== Sensors snapshot summary: ===\n");
+        g_sensor_snapshot->PrintSummary();
+    }
+} // namespace dbus_top_analyzer
+
+void DBusTopStatistics::OnNewDBusMessage(const char* sender,
+                                         const char* destination,
+                                         const char* interface,
+                                         const char* path, const char* member,
+                                         const char type, sd_bus_message* m)
+{
+    num_messages_++;
+    std::vector<std::string> keys;
+
+    std::string sender_orig = CheckAndFixNullString(sender);
+    std::string dest_orig = CheckAndFixNullString(destination);
+    // For method return messages, we actually want to show the sender
+    // and destination of the original method call, so we swap the
+    // sender and destination
+    if (type == 2)
+    { // DBUS_MESSAGE_TYPE_METHOD_METHOD_RETURN
+        std::swap(sender_orig, dest_orig);
+    }
+
+    // Special case: when PID == 1 (init), the DBus unit would be systemd.
+    // It seems it was not possible to obtain the connection name of systemd
+    // so we manually set it here.
+    const int sender_orig_pid =
+        g_connection_snapshot->GetConnectionPIDFromNameOrUniqueName(
+            sender_orig);
+
+    if (sender_orig_pid == 1)
+    {
+        sender_orig = "systemd";
+    }
+    const int dest_orig_pid =
+        g_connection_snapshot->GetConnectionPIDFromNameOrUniqueName(dest_orig);
+    if (dest_orig_pid == 1)
+    {
+        dest_orig = "systemd";
+    }
+
+    for (DBusTopSortField field : fields_)
+    {
+        switch (field)
+        {
+            case kSender:
+                keys.push_back(sender_orig);
+                break;
+            case kDestination:
+                keys.push_back(dest_orig);
+                break;
+            case kInterface:
+                keys.push_back(CheckAndFixNullString(interface));
+                break;
+            case kPath:
+                keys.push_back(CheckAndFixNullString(path));
+                break;
+            case kMember:
+                keys.push_back(CheckAndFixNullString(member));
+                break;
+            case kSenderPID:
+            {
+                if (sender_orig_pid != INVALID)
+                {
+                    keys.push_back(std::to_string(sender_orig_pid));
+                }
+                else
+                {
+                    keys.push_back("(unknown)");
+                }
+                break;
+            }
+            case kSenderCMD:
+            {
+                keys.push_back(
+                    g_connection_snapshot->GetConnectionCMDFromNameOrUniqueName(
+                        sender_orig));
+                break;
+            }
+            case kMsgPerSec:
+            case kAverageLatency:
+                break; // Don't populate "keys" using these 2 fields
+        }
+    }
+    // keys = combination of fields of user's choice
+
+    if (stats_.count(keys) == 0)
+    {
+        stats_[keys] = DBusTopComputedMetrics();
+    }
+    // Need to update msg/s regardless
+    switch (type)
+    {
+        case 1: // DBUS_MESSAGE_TYPE_METHOD_CALL
+            stats_[keys].num_method_calls++;
+            break;
+        case 2: // DBUS_MESSAGE_TYPE_METHOD_METHOD_RETURN
+            stats_[keys].num_method_returns++;
+            break;
+        case 3: // DBUS_MESSAGE_TYPE_ERROR
+            stats_[keys].num_errors++;
+            break;
+        case 4: // DBUS_MESSAGE_TYPE_SIGNAL
+            stats_[keys].num_signals++;
+            break;
+    }
+    // Update global latency histogram
+    // For method call latency
+    if (type == 1) // DBUS_MESSAGE_TYPE_METHOD_CALL
+    {
+        uint64_t serial; // serial == cookie
+        sd_bus_message_get_cookie(m, &serial);
+        in_flight_methodcalls[serial] = Microseconds();
+    }
+    else if (type == 2) // DBUS_MESSAGE_TYPE_MEHOTD_RETURN
+    {
+        uint64_t reply_serial = 0; // serial == cookie
+        sd_bus_message_get_reply_cookie(m, &reply_serial);
+        if (in_flight_methodcalls.count(reply_serial) > 0)
+        {
+            float dt_usec =
+                Microseconds() - in_flight_methodcalls[reply_serial];
+            in_flight_methodcalls.erase(reply_serial);
+            dbus_top_analyzer::g_mc_time_histogram.AddSample(dt_usec);
+
+            // Add method call count and total latency to the corresponding key
+            stats_[keys].total_latency_usec += dt_usec;
+        }
+    }
+    // For meaning of type see here
+    // https://dbus.freedesktop.org/doc/api/html/group__DBusProtocol.html#ga4a9012edd7f22342f845e98150aeb858
+    switch (type)
+    {
+        case 1:
+            num_mc_++;
+            break;
+        case 2:
+            num_mr_++;
+            break;
+        case 3:
+            num_error_++;
+            break;
+        case 4:
+            num_sig_++;
+            break;
+    }
+}
diff --git a/dbus-top/analyzer.hpp b/dbus-top/analyzer.hpp
new file mode 100644
index 0000000..2284c7f
--- /dev/null
+++ b/dbus-top/analyzer.hpp
@@ -0,0 +1,177 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include "histogram.hpp"
+
+#include <systemd/sd-bus.h>
+
+#include <atomic>
+#include <map>
+#include <mutex>
+#include <string>
+#include <vector>
+
+enum DBusTopSortField
+{
+    // DBus Message properties
+    kSender,
+    kDestination,
+    kInterface,
+    kPath,
+    kMember,
+    kSenderPID,
+    kSenderCMD,
+    // Computed metrics
+    kMsgPerSec,
+    kAverageLatency,
+};
+
+const std::string FieldNames[] = {"Sender",     "Destination", "Interface",
+                                  "Path",       "Member",      "Sender PID",
+                                  "Sender CMD", "Msg/s",       "Avg Latency"};
+const int FieldPreferredWidths[] = {18, 20, 12, 10, 10, 10, 25, 8, 12};
+bool DBusTopSortFieldIsNumeric(DBusTopSortField field);
+
+struct DBusTopComputedMetrics
+{
+    DBusTopComputedMetrics()
+    {
+        num_signals = 0;
+        num_errors = 0;
+        num_method_returns = 0;
+        num_method_calls = 0;
+        total_latency_usec = 0;
+    }
+    int num_method_returns = 0;
+    int num_errors = 0;
+    int num_signals = 0;
+    int num_method_calls;
+    uint64_t total_latency_usec;
+};
+
+class DBusTopStatistics
+{
+  public:
+    int num_messages_;
+    int num_mc_, num_mr_, num_sig_, num_error_;
+    float seconds_since_last_sample_;
+    std::vector<DBusTopSortField> fields_;
+    std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_;
+    DBusTopStatistics() :
+        num_messages_(0), num_mc_(0), num_mr_(0), num_sig_(0), num_error_(0),
+        seconds_since_last_sample_(0)
+    {
+        fields_ = {kSender, kDestination, kSenderPID, kSenderCMD};
+        stats_.clear();
+    }
+
+    std::vector<DBusTopSortField> GetFields()
+    {
+        return fields_;
+    }
+
+    std::vector<std::string> GetFieldNames()
+    {
+        const int N = fields_.size();
+        std::vector<std::string> ret(N);
+        for (int i = 0; i < static_cast<int>(fields_.size()); i++)
+        {
+            ret[i] = FieldNames[static_cast<int>(fields_[i])];
+        }
+        return ret;
+    }
+
+    std::vector<int> GetFieldPreferredWidths()
+    {
+        const int N = fields_.size();
+        std::vector<int> ret(N);
+        for (int i = 0; i < static_cast<int>(fields_.size()); i++)
+        {
+            ret[i] = FieldPreferredWidths[static_cast<int>(fields_[i])];
+        }
+        return ret;
+    }
+
+    void Reset()
+    {
+        num_messages_ = 0;
+        num_mc_ = 0;
+        num_mr_ = 0;
+        num_sig_ = 0;
+        num_error_ = 0;
+        stats_.clear();
+    }
+    
+    void SetSortFieldsAndReset(const std::vector<DBusTopSortField>& f)
+    {
+        num_messages_ = 0;
+        num_mc_ = 0;
+        num_mr_ = 0;
+        num_sig_ = 0;
+        num_error_ = 0;
+        stats_.clear();
+        fields_ = f;
+    }
+
+    void Assign(DBusTopStatistics* out)
+    {
+        out->num_messages_ = this->num_messages_;
+        out->num_mc_ = this->num_mc_;
+        out->num_mr_ = this->num_mr_;
+        out->num_sig_ = this->num_sig_;
+        out->num_error_ = this->num_error_;
+        out->seconds_since_last_sample_ = this->seconds_since_last_sample_;
+        out->fields_ = this->fields_;
+        out->stats_ = this->stats_;
+    }
+
+    void OnNewDBusMessage(const char* sender, const char* destination,
+                          const char* interface, const char* path,
+                          const char* message, const char type,
+                          sd_bus_message* m);
+    std::string CheckAndFixNullString(const char* x)
+    {
+        if (x == nullptr)
+            return "(null)";
+        else
+            return std::string(x);
+    }
+
+    std::map<std::vector<std::string>, DBusTopComputedMetrics> StatsSnapshot()
+    {
+        std::map<std::vector<std::string>, DBusTopComputedMetrics> ret;
+        ret = stats_;
+        return ret;
+    }
+
+  private:
+    std::mutex mtx_;
+};
+
+int GetSummaryIntervalInMillises();
+// Monitor sensor details-related DBus method calls/replies
+// typedef void (*SetDBusTopConnection)(const char* conn);
+namespace dbus_top_analyzer
+{
+    void Process();
+    void Finish();
+    typedef void (*DBusTopStatisticsCallback)(DBusTopStatistics*,
+                                            Histogram<float>*);
+    void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb);
+    void AnalyzerThread();
+    // Methods for sending Object Mapper queries
+    void ListAllSensors();
+} // namespace dbus_top_analyzer
diff --git a/dbus-top/bargraph.hpp b/dbus-top/bargraph.hpp
new file mode 100644
index 0000000..36f34a1
--- /dev/null
+++ b/dbus-top/bargraph.hpp
@@ -0,0 +1,59 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdio.h>
+
+#include <vector>
+
+template <typename ValueType>
+class BarGraph
+{
+  public:
+    std::vector<ValueType> history_; // is actually a ring buffer.
+    int next_;   // index to the slot where the next insertion will go
+    int length_; // total # of data points that have ever been added
+    explicit BarGraph(int capacity) : next_(0), length_(0)
+    {
+        history_.resize(capacity);
+        std::fill(history_.begin(), history_.end(), 0);
+    }
+
+    // The last value is in [0], so on and so forth
+    // Note: if there are not enough data, this function will return as much
+    // as is available
+    std::vector<float> GetLastNValues(int x)
+    {
+        std::vector<float> ret;
+        const int N = static_cast<int>(history_.size());
+        int imax = x;
+        imax = std::min(imax, length_);
+        imax = std::min(imax, N);
+        int idx = (next_ - 1 + N) % N;
+        for (int i = 0; i < imax; i++)
+        {
+            ret.push_back(history_[idx]);
+            idx = (idx - 1 + N) % N;
+        }
+        return ret;
+    }
+
+    void AddValue(ValueType x)
+    {
+        history_[next_] = x;
+        next_ = (next_ + 1) % history_.size();
+        length_++;
+    }
+};
diff --git a/dbus-top/dbus_capture.cpp b/dbus-top/dbus_capture.cpp
new file mode 100644
index 0000000..715fd41
--- /dev/null
+++ b/dbus-top/dbus_capture.cpp
@@ -0,0 +1,205 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "analyzer.hpp"
+#include "histogram.hpp"
+#include "sensorhelper.hpp"
+#include "main.hpp"
+
+#include <ncurses.h>
+#include <stdlib.h>
+#include <systemd/sd-bus.h>
+
+#include <unordered_map>
+
+bool IS_USER_BUS = false; // User bus or System bus?
+extern sd_bus* g_bus;
+extern DBusConnectionSnapshot* g_connection_snapshot;
+static std::unordered_map<uint64_t, uint64_t> in_flight_methodcalls;
+
+namespace dbus_top_analyzer
+{
+    extern DBusTopStatistics g_dbus_statistics;
+    extern Histogram<float> g_mc_time_histogram;
+} // namespace dbus_top_analyzer
+
+static void TrackMessage(sd_bus_message* m)
+{}
+// Obtain a Monitoring DBus connection
+int AcquireBus(sd_bus** ret)
+{
+    int r;
+    r = sd_bus_new(ret);
+    if (r < 0)
+    {
+        printf("Could not allocate bus: %s\n", strerror(-r));
+        return 0;
+    }
+    r = sd_bus_set_monitor(*ret, true);
+    if (r < 0)
+    {
+        printf("Could not set monitor mode: %s\n", strerror(-r));
+        return 0;
+    }
+    r = sd_bus_negotiate_creds(*ret, true, _SD_BUS_CREDS_ALL);
+    if (r < 0)
+    {
+        printf("Could not enable credentials: %s\n", strerror(-r));
+        return 0;
+    }
+    r = sd_bus_negotiate_timestamp(*ret, true);
+    if (r < 0)
+    {
+        printf("Could not enable timestamps: %s\n", strerror(-r));
+        return 0;
+    }
+    r = sd_bus_negotiate_fds(*ret, true);
+    if (r < 0)
+    {
+        printf("Could not enable fds: %s\n", strerror(-r));
+        return 0;
+    }
+    r = sd_bus_set_bus_client(*ret, true);
+    if (r < 0)
+    {
+        printf("Could not enable bus client: %s\n", strerror(-r));
+        return 0;
+    }
+    if (IS_USER_BUS)
+    {
+        r = sd_bus_set_address(*ret, "haha");
+        if (r < 0)
+        {
+            printf("Could not set user bus: %s\n", strerror(-r));
+            return 0;
+        }
+    }
+    else
+    {
+        r = sd_bus_set_address(*ret, "unix:path=/run/dbus/system_bus_socket");
+        if (r < 0)
+        {
+            printf("Could not set system bus: %s\n", strerror(-r));
+            return 0;
+        }
+    }
+    r = sd_bus_start(*ret);
+    if (r < 0)
+    {
+        printf("Could not connect to bus: %s\n", strerror(-r));
+        return 0;
+    }
+    return r;
+}
+
+void DbusCaptureThread()
+{
+    int r;
+    // Become Monitor
+    uint32_t flags = 0;
+    sd_bus_message* message;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    r = sd_bus_message_new_method_call(
+        g_bus, &message, "org.freedesktop.DBus", "/org/freedesktop/DBus",
+        "org.freedesktop.DBus.Monitoring", "BecomeMonitor");
+    if (r < 0)
+    {
+        printf("Could not create the BecomeMonitor function call\n");
+        exit(0);
+    }
+    // Match conditions
+    r = sd_bus_message_open_container(message, 'a', "s");
+    if (r < 0)
+    {
+        printf("Could not open container\n");
+        exit(0);
+    }
+    r = sd_bus_message_close_container(message);
+    if (r < 0)
+    {
+        printf("Could not close container\n");
+        exit(0);
+    }
+    r = sd_bus_message_append_basic(message, 'u', &flags);
+    if (r < 0)
+    {
+        printf("Could not append flags\n");
+        exit(0);
+    }
+    r = sd_bus_call(g_bus, message, 0, &error, nullptr);
+    if (r < 0)
+    {
+        printf("Could not call org.freedesktop.DBus.Monitoring.BecomeMonitor "
+               "%d, %s\n",
+               r, strerror(-r));
+        exit(0);
+    }
+    const char* unique_name;
+    r = sd_bus_get_unique_name(g_bus, &unique_name);
+    if (r < 0)
+    {
+        printf("Could not get unique name: %s\n", strerror(-r));
+        exit(0);
+    }
+    // Enter packet processing loop
+    while (true)
+    {
+        struct sd_bus_message* m = nullptr;
+        r = sd_bus_process(g_bus, &m);
+        if (m != nullptr)
+        {
+            if (r < 0)
+            {
+                printf("Failed to call sd_bus_process: %s\n", strerror(-r));
+            }
+            uint8_t type;
+            r = sd_bus_message_get_type(m, &type);
+            const char* path = sd_bus_message_get_path(m);
+            // const char* iface = sd_bus_message_get_interface(m);
+            const char* sender = sd_bus_message_get_sender(m);
+            const char* destination = sd_bus_message_get_destination(m);
+            const char* interface = sd_bus_message_get_interface(m);
+            const char* member = sd_bus_message_get_member(m);
+            // TODO: This is for the bottom-left window
+            TrackMessage(m);
+
+            // Look up the unique connection name for sender and destination
+            std::string sender_uniq, dest_uniq;
+            if (sender != nullptr)
+            {
+                sender_uniq =
+                    g_connection_snapshot->GetUniqueNameIfExists(sender);
+            }
+            if (destination != nullptr)
+            {
+                dest_uniq =
+                    g_connection_snapshot->GetUniqueNameIfExists(destination);
+            }
+            // This is for the bottom-right window
+            dbus_top_analyzer::g_dbus_statistics.OnNewDBusMessage(
+            sender_uniq.c_str(), dest_uniq.c_str(), interface, path, member,
+                type, m);
+            sd_bus_message_unref(m);
+        }
+        r = sd_bus_wait(g_bus,
+                        (uint64_t)(GetSummaryIntervalInMillises() * 1000));
+        if (r < 0)
+        {
+            printf("Failed to wait on bus: %s\n", strerror(-r));
+            abort();
+        }
+        // Perform one analysis step
+        dbus_top_analyzer::Process();
+    }
+}
\ No newline at end of file
diff --git a/dbus-top/dbus_capture.hpp b/dbus-top/dbus_capture.hpp
new file mode 100644
index 0000000..825a519
--- /dev/null
+++ b/dbus-top/dbus_capture.hpp
@@ -0,0 +1,20 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <systemd/sd-bus.h>
+
+int AcquireBus(sd_bus** ret);
+void DbusCaptureThread();
diff --git a/dbus-top/dbus_top_recipe.bb b/dbus-top/dbus_top_recipe.bb
new file mode 100644
index 0000000..4de4f0e
--- /dev/null
+++ b/dbus-top/dbus_top_recipe.bb
@@ -0,0 +1,23 @@
+HOMEPAGE = "http://github.com/openbmc/openbmc-tools"
+PR = "r1"
+PV = "1.0+git${SRCPV}"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://../LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
+
+SRC_URI += "git://github.com/openbmc-tools"
+SRCREV = "4a0e2e3c10327dac1c923d263929be9a20478b24"
+
+S = "${WORKDIR}/git/"
+inherit meson
+
+SUMMARY = "DBus-Top"
+DESCRIPTION = "DBUs-Top."
+GOOGLE_MISC_PROJ = "dbus-top"
+
+DEPENDS += "systemd"
+DEPENDS += "sdbusplus"
+DEPENDS += "phosphor-mapper"
+DEPENDS += "ncurses"
+
+inherit systemd
diff --git a/dbus-top/histogram.hpp b/dbus-top/histogram.hpp
new file mode 100644
index 0000000..750a9f4
--- /dev/null
+++ b/dbus-top/histogram.hpp
@@ -0,0 +1,184 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+#include <math.h>
+#include <stdio.h>
+
+#include <vector>
+template <typename ValueType>
+class Histogram
+{
+  public:
+    Histogram()
+    {
+        num_entries_ = 0;
+        num_low_outliers_ = 0;
+        num_high_outliers_ = 0;
+        low_percentile_ = 0;
+        high_percentile_ = 0;
+        SetWindowSize(10000);
+        SetCumulativeDensityThresholds(0.01f, 0.99f);
+    }
+
+    void AddSample(ValueType s)
+    {
+        int N = static_cast<int>(samples_.size());
+        samples_[num_entries_ % N] = s;
+        num_entries_++;
+    }
+
+    void SetBucketCount(int bc)
+    {
+        buckets_.resize(bc);
+    }
+
+    void SetWindowSize(int s)
+    {
+        samples_.resize(s);
+    }
+
+    void SetCumulativeDensityThresholds(float low_cd, float high_cd)
+    {
+        low_cum_density_ = low_cd;
+        high_cum_density_ = high_cd;
+    }
+
+    void ComputeHistogram()
+    {
+        const int NS = static_cast<int>(samples_.size());
+        int N = NS;
+        if (num_entries_ < N)
+        {
+            N = num_entries_;
+        }
+        if (N <= 0)
+        {
+            return;
+        }
+        std::vector<ValueType> sorted;
+        if (N == NS)
+            sorted = samples_;
+        else
+            sorted.insert(sorted.end(), samples_.begin(), samples_.begin() + N);
+        sort(sorted.begin(), sorted.end());
+        int idx_low = static_cast<int>(N * low_cum_density_);
+        int idx_high = static_cast<int>(N * high_cum_density_);
+        if (idx_high - idx_low + 1 < 1)
+        {
+            return; // No entries can be shown, quit
+        }
+        max_bucket_height_ = 0;
+        ValueType value_low = sorted[idx_low];
+        ValueType value_high = sorted[idx_high];
+        low_percentile_ = value_low;
+        high_percentile_ = value_high;
+        const int NB = static_cast<int>(buckets_.size()); // Number of Bins
+        float bucket_width = (value_high - value_low) / NB;
+        // If all values are the same, manually extend the range to
+        // (value-1, value+1)
+        const float EPS = 1e-4;
+        if (fabs(value_high - value_low) <= EPS)
+        {
+            value_low = value_low - 1;
+            value_high = value_high + 1;
+            bucket_width = (value_high - value_low) / NB;
+        }
+        else
+        {}
+        buckets_.assign(NB, 0);
+        num_low_outliers_ = 0;
+        num_high_outliers_ = 0;
+        for (int i = idx_low; i <= idx_high; i++)
+        {
+            ValueType v = sorted[i];
+            ValueType dist = (v - value_low);
+            int bucket_idx = dist / bucket_width;
+            if (bucket_idx < 0)
+            {
+                num_low_outliers_++;
+            }
+            else if (bucket_idx >= NB)
+            {
+                num_high_outliers_++;
+            }
+            else
+            {
+                buckets_[bucket_idx]++;
+                max_bucket_height_ =
+                    std::max(max_bucket_height_, buckets_[bucket_idx]);
+            }
+        }
+    }
+
+    int BucketHeight(int idx)
+    {
+        if (idx < 0 || idx >= static_cast<int>(buckets_.size()))
+            return 0;
+        return buckets_[idx];
+    }
+    
+    void Assign(Histogram<ValueType>* out)
+    {
+        out->num_entries_ = num_entries_;
+        out->samples_ = samples_;
+        out->num_low_outliers_ = num_low_outliers_;
+        out->num_high_outliers_ = num_high_outliers_;
+        out->buckets_ = buckets_;
+        out->low_cum_density_ = low_cum_density_;
+        out->high_cum_density_ = high_cum_density_;
+        out->low_percentile_ = low_percentile_;
+        out->high_percentile_ = high_percentile_;
+        out->max_bucket_height_ = max_bucket_height_;
+    }
+
+    int MaxBucketHeight()
+    {
+        return max_bucket_height_;
+    }
+
+    ValueType LowPercentile()
+    {
+        return low_percentile_;
+    }
+
+    ValueType HighPercentile()
+    {
+        return high_percentile_;
+    }
+
+    float LowCumDensity()
+    {
+        return low_cum_density_;
+    }
+
+    float HighCumDensity()
+    {
+        return high_cum_density_;
+    }
+
+    bool Empty()
+    {
+        return num_entries_ == 0;
+    }
+    
+    int num_entries_;
+    std::vector<ValueType> samples_;
+    int num_low_outliers_, num_high_outliers_;
+    std::vector<int> buckets_;
+    float low_cum_density_, high_cum_density_;
+    // "1% percentile" means "1% of the samples are below this value"
+    ValueType low_percentile_, high_percentile_;
+    int max_bucket_height_;
+};
\ No newline at end of file
diff --git a/dbus-top/main.cpp b/dbus-top/main.cpp
new file mode 100644
index 0000000..d56b72e
--- /dev/null
+++ b/dbus-top/main.cpp
@@ -0,0 +1,392 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "main.hpp"
+
+#include "analyzer.hpp"
+#include "bargraph.hpp"
+#include "dbus_capture.hpp"
+#include "histogram.hpp"
+#include "menu.hpp"
+#include "sensorhelper.hpp"
+#include "views.hpp"
+
+#include <fmt/printf.h>
+#include <ncurses.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <iomanip>
+#include <sstream>
+#include <thread>
+
+DBusTopWindow* g_current_active_view;
+SummaryView* g_summary_window;
+SensorDetailView* g_sensor_detail_view;
+DBusStatListView* g_dbus_stat_list_view;
+FooterView* g_footer_view;
+BarGraph<float>* g_bargraph = nullptr;
+Histogram<float>* g_histogram;
+std::vector<DBusTopWindow*> g_views;
+int g_highlighted_view_index = INVALID;
+sd_bus* g_bus = nullptr;
+SensorSnapshot* g_sensor_snapshot;
+DBusConnectionSnapshot* g_connection_snapshot;
+DBusTopStatistics* g_dbus_statistics; // At every update interval,
+                                      // dbus_top_analyzer::g_dbus_statistics's
+                                      // value is copied to this one for display
+void ReinitializeUI();
+int maxx, maxy, halfx, halfy;
+
+void ActivateWindowA()
+{
+    g_views[0]->visible_=true;
+    g_views[0]->maximize_=true;
+    g_views[1]->visible_=false;
+    g_views[2]->visible_=false;
+}
+
+void ActivateWindowB()
+{
+    g_views[1]->visible_=true;
+    g_views[1]->maximize_=true;
+    g_views[0]->visible_=false;
+    g_views[2]->visible_=false;
+}
+void ActivateWindowC()
+{
+    g_views[2]->visible_=true;
+    g_views[2]->maximize_=true;
+    g_views[0]->visible_=false;
+    g_views[1]->visible_=false;
+}
+void ActivateAllWindows()
+{
+    g_views[0]->maximize_ = false;
+    g_views[1]->maximize_=false;
+    g_views[2]->maximize_=false;
+    g_views[0]->visible_=true;
+    g_views[1]->visible_=true;
+    g_views[2]->visible_= true;
+}
+
+void InitColorPairs()
+{
+    init_pair(1, COLOR_WHITE, COLOR_BLACK); // Does not work on actual machine
+    init_pair(2, COLOR_BLACK, COLOR_WHITE);
+}
+
+// Returns number of lines drawn
+int DrawTextWithWidthLimit(WINDOW* win, std::string txt, int y, int x,
+                           int width, const std::string& delimiters)
+{
+    int ret = 0;
+    std::string curr_word, curr_line;
+    while (txt.empty() == false)
+    {
+        ret++;
+        if (static_cast<int>(txt.size()) > width)
+        {
+            mvwprintw(win, y, x, txt.substr(0, width).c_str());
+            txt = txt.substr(width);
+        }
+        else
+        {
+            mvwprintw(win, y, x, txt.c_str());
+            break;
+        }
+        y++;
+    }
+    return ret;
+}
+
+void UpdateWindowSizes()
+{
+    /* calculate window sizes and locations */
+    if (getenv("FIXED_TERMINAL_SIZE"))
+    {
+        maxx = 100;
+        maxy = 30;
+    }
+    else
+    {
+        getmaxyx(stdscr, maxy, maxx);
+        halfx = maxx >> 1;
+        halfy = maxy >> 1;
+    }
+    for (DBusTopWindow* v : g_views)
+    {
+        v->OnResize(maxx, maxy);
+        if(v->maximize_){
+            v->rect={0,0,maxx,maxy-MARGIN_BOTTOM};
+            v->UpdateWindowSizeAndPosition();
+        }
+    }
+}
+
+std::string FloatToString(float value)
+{
+    return fmt::sprintf("%.2f", value);
+}
+
+void DBusTopRefresh()
+{
+    UpdateWindowSizes();
+    for (DBusTopWindow* v : g_views)
+    {
+        v->Render();
+    }
+    DBusTopWindow* focused_view = g_current_active_view;
+    if (focused_view)
+    {
+        focused_view->DrawBorderIfNeeded(); // focused view border: on top
+    }
+    refresh();
+}
+
+// This function is called by the Capture thread
+void DBusTopStatisticsCallback(DBusTopStatistics* stat, Histogram<float>* hist)
+{
+    if (stat == nullptr)
+        return;
+    // Makes a copy for display
+    // TODO: Add a mutex here for safety
+    stat->Assign(g_dbus_statistics);
+    hist->Assign(g_histogram);
+    float interval_secs = stat->seconds_since_last_sample_;
+    if (interval_secs == 0)
+    {
+        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
+    }
+    g_summary_window->UpdateDBusTopStatistics(stat);
+    stat->SetSortFieldsAndReset(g_dbus_stat_list_view->GetSortFields());
+    // ReinitializeUI(); // Don't do it here, only when user presses [R]
+    DBusTopRefresh();
+}
+
+void CycleHighlightedView()
+{
+    int new_index = 0;
+    if (g_highlighted_view_index == INVALID)
+    {
+        new_index = 0;
+    }
+    else
+    {
+        new_index = g_highlighted_view_index + 1;
+    }
+    while (new_index < static_cast<int>(g_views.size()) &&
+           g_views[new_index]->selectable_ == false)
+    {
+        new_index++;
+    }
+    if (new_index >= static_cast<int>(g_views.size()))
+    {
+        new_index = INVALID;
+    }
+    // Un-highlight all
+    for (DBusTopWindow* v : g_views)
+    {
+        v->focused_ = false;
+    }
+    if (new_index != INVALID)
+    {
+        g_views[new_index]->focused_ = true;
+        g_current_active_view = g_views[new_index];
+    }
+    else
+    {
+        g_current_active_view = nullptr;
+    }
+    g_highlighted_view_index = new_index;
+    DBusTopRefresh();
+}
+
+int UserInputThread()
+{
+    while (true)
+    {
+        int c = getch();
+        DBusTopWindow* curr_view = g_current_active_view;
+        // If a view is currently focused on
+        if (curr_view)
+        {
+            switch (c)
+            {
+                case '\e': // 27 in dec, 0x1B in hex, escape key
+                {
+                    getch();
+                    c = getch();
+                    switch (c)
+                    {
+                        case 'A':
+                            curr_view->OnKeyDown("up");
+                            break;
+                        case 'B':
+                            curr_view->OnKeyDown("down");
+                            break;
+                        case 'C':
+                            curr_view->OnKeyDown("right");
+                            break;
+                        case 'D':
+                            curr_view->OnKeyDown("left");
+                            break;
+                        case '\e':
+                            curr_view->OnKeyDown("escape");
+                            break;
+                    }
+                    break;
+                }
+                case '\n': // 10 in dec, 0x0A in hex, line feed
+                {
+                    curr_view->OnKeyDown("enter");
+                    break;
+                }
+                case 'q':
+                case 'Q': // Q key
+                {
+                    curr_view->OnKeyDown("escape");
+                    break;
+                }
+                case 'a':
+                case 'A': // A key
+                {
+                    curr_view->OnKeyDown("a");
+                    break;
+                }
+                case 'd':
+                case 'D': // D key
+                {
+                    curr_view->OnKeyDown("d");
+                    break;
+                }
+                case 33: // Page up
+                {
+                    curr_view->OnKeyDown("pageup");
+                    break;
+                }
+                case 34: // Page down
+                {
+                    curr_view->OnKeyDown("pagedown");
+                    break;
+                }
+                case ' ': // Spacebar
+                {
+                    curr_view->OnKeyDown("space");
+                    break;
+                }
+            }
+        }
+        // The following keys are registered both when a view is selected and
+        // when it is not
+        switch (c)
+        {
+            case '\t': // 9 in dec, 0x09 in hex, tab
+            {
+                CycleHighlightedView();
+                break;
+            }
+            case 'r':
+            case 'R':
+            {
+                ReinitializeUI();
+                DBusTopRefresh();
+                break;
+            }
+            case 'x':
+            case 'X':
+            {
+                clear();
+                ActivateWindowA();
+                break;
+            }
+            case 'y':
+            case 'Y':
+            {
+                clear();
+                ActivateWindowB();
+                break;
+            }
+            case 'z':
+            case 'Z':
+            {
+                clear();
+                ActivateWindowC();
+                break;
+            }
+            case 'h':
+            case 'H':
+            {
+                ActivateAllWindows();
+                DBusTopRefresh();
+            }
+            default:
+                break;
+        }
+    }
+    exit(0);
+}
+
+void ReinitializeUI()
+{
+    endwin();
+    initscr();
+    use_default_colors();
+    noecho();
+    for (int i = 0; i < static_cast<int>(g_views.size()); i++)
+    {
+        g_views[i]->RecreateWindow();
+    }
+}
+
+int main(int argc, char** argv)
+{
+    int r = AcquireBus(&g_bus);
+    if (r <= 0)
+    {
+        printf("Error acquiring bus for monitoring\n");
+        exit(0);
+    }
+
+    printf("Listing all sensors for display\n");
+    // ListAllSensors creates connection snapshot and sensor snapshot
+    dbus_top_analyzer::ListAllSensors();
+    g_bargraph = new BarGraph<float>(300);
+    g_histogram = new Histogram<float>();
+
+    initscr();
+    use_default_colors();
+    start_color();
+    noecho();
+
+    clear();
+    g_dbus_statistics = new DBusTopStatistics();
+    g_summary_window = new SummaryView();
+    g_sensor_detail_view = new SensorDetailView();
+    g_dbus_stat_list_view = new DBusStatListView();
+    g_footer_view = new FooterView();
+    g_views.push_back(g_summary_window);
+    g_views.push_back(g_sensor_detail_view);
+    g_views.push_back(g_dbus_stat_list_view);
+    g_views.push_back(g_footer_view);
+
+    g_sensor_detail_view->UpdateSensorSnapshot(g_sensor_snapshot);
+    UpdateWindowSizes();
+    dbus_top_analyzer::SetDBusTopStatisticsCallback(&DBusTopStatisticsCallback);
+    std::thread capture_thread(DbusCaptureThread);
+    std::thread user_input_thread(UserInputThread);
+    capture_thread.join();
+
+    return 0;
+}
diff --git a/dbus-top/main.hpp b/dbus-top/main.hpp
new file mode 100644
index 0000000..91c07da
--- /dev/null
+++ b/dbus-top/main.hpp
@@ -0,0 +1,37 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include "bargraph.hpp"
+
+#include <ncurses.h>
+
+#include <string>
+
+const int INVALID = -999; // Constant indicating invalid indices
+struct Rect
+{
+    int x, y, w, h; // X, Y, Width, Height
+    Rect(int _x, int _y, int _w, int _h) : x(_x), y(_y), w(_w), h(_h)
+    {}
+    Rect() : x(0), y(0), w(1), h(1)
+    {}
+};
+
+int DrawTextWithWidthLimit(WINDOW* win, std::string txt, int y, int x,
+                           int width, const std::string& delimiters);
+std::string FloatToString(float value);
+template <typename T>
+void HistoryBarGraph(WINDOW* win, const Rect& rect, BarGraph<T>* bargraph);
diff --git a/dbus-top/menu.cpp b/dbus-top/menu.cpp
new file mode 100644
index 0000000..af59f14
--- /dev/null
+++ b/dbus-top/menu.cpp
@@ -0,0 +1,322 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "menu.hpp"
+
+#include "views.hpp"
+
+ArrowKeyNavigationMenu::ArrowKeyNavigationMenu(DBusTopWindow* view) :
+    win_(view->win), parent_(view), idx0_(INVALID), idx1_(INVALID),
+    h_padding_(2), col_width_(15), h_spacing_(2), choice_(INVALID)
+{}
+
+void ArrowKeyNavigationMenu::do_Render(bool is_column_major)
+{
+    const int nrows = DispEntriesPerColumn();
+    const int ncols = DispEntriesPerRow();
+    const int items_per_page = nrows * ncols;
+    if (items_per_page < 1)
+        return;
+    int tot_num_items = items_.size();
+    // int tot_num_columns = (tot_num_items - 1) / nrows + 1;
+    // Determine whether cursor is outside the current rectangular viewport
+    bool is_cursor_out_of_view = false;
+    if (idx0_ > choice_ || idx1_ <= choice_)
+    {
+        is_cursor_out_of_view = true;
+    }
+    if (idx0_ == INVALID || idx1_ == INVALID)
+    {
+        is_cursor_out_of_view = true;
+    }
+    // Scroll the viewport such that it contains the cursor
+    if (is_cursor_out_of_view)
+    {
+        idx0_ = 0;
+        idx1_ = items_per_page;
+    }
+    while (idx1_ <= choice_)
+    {
+        if (is_column_major)
+        {
+            idx0_ += nrows;
+            idx1_ += nrows;
+        }
+        else
+        {
+            idx0_ += ncols;
+            idx1_ += ncols;
+        }
+    }
+    int y0 = rect_.y, x0 = rect_.x;
+    int y = y0, x = x0;
+    for (int i = 0; i < items_per_page; i++)
+    {
+        int idx = idx0_ + i;
+        if (idx < tot_num_items)
+        {
+            if (idx == choice_)
+            {
+                wattrset(win_, A_REVERSE);
+            }
+            std::string s = items_[idx];
+            while (s.size() < col_width_)
+            {
+                s.push_back(' ');
+            }
+            mvwprintw(win_, y, x, s.c_str());
+            wattrset(win_, 0);
+        }
+        else
+        {
+            break;
+        }
+        if (is_column_major)
+        {
+            y++;
+            if (i % nrows == nrows - 1)
+            {
+                y = y0;
+                x += col_width_ + h_spacing_;
+            }
+        }
+        else
+        {
+            x += col_width_ + h_spacing_;
+            if (i % ncols == ncols - 1)
+            {
+                x = x0;
+                y++;
+            }
+        }
+    }
+}
+
+void ArrowKeyNavigationMenu::Render()
+{
+    do_Render(order == ColumnMajor);
+}
+
+void ArrowKeyNavigationMenu::OnKeyDown(const std::string& key)
+{
+    switch (order)
+    {
+        case ColumnMajor:
+            if (key == "up")
+            {
+                MoveCursorAlongPrimaryAxis(-1);
+            }
+            else if (key == "down")
+            {
+                MoveCursorAlongPrimaryAxis(1);
+            }
+            else if (key == "left")
+            {
+                MoveCursorAlongSecondaryAxis(-1);
+            }
+            else if (key == "right")
+            {
+                MoveCursorAlongSecondaryAxis(1);
+            }
+            break;
+        case RowMajor:
+            if (key == "up")
+            {
+                MoveCursorAlongSecondaryAxis(-1);
+            }
+            else if (key == "down")
+            {
+                MoveCursorAlongSecondaryAxis(1);
+            }
+            else if (key == "left")
+            {
+                MoveCursorAlongPrimaryAxis(-1);
+            }
+            else if (key == "right")
+            {
+                MoveCursorAlongPrimaryAxis(1);
+            }
+            break;
+            break;
+    }
+}
+
+void ArrowKeyNavigationMenu::MoveCursorAlongPrimaryAxis(int delta)
+{
+    const int N = items_.size();
+    if (N < 1)
+        return;
+    // If the cursor is inactive, activate it
+    if (choice_ == INVALID)
+    {
+        if (delta > 0)
+        {
+            choice_ = 0;
+        }
+        else
+        {
+            choice_ = N - 1;
+        }
+        return;
+    }
+    int choice_next = choice_ + delta;
+    while (choice_next >= N)
+    {
+        choice_next -= N;
+    }
+    while (choice_next < 0)
+    {
+        choice_next += N;
+    }
+    choice_ = choice_next;
+}
+
+void ArrowKeyNavigationMenu::MoveCursorAlongSecondaryAxis(int delta)
+{
+    if (delta != 0 && delta != 1 && delta != -1)
+        return;
+    const int N = items_.size();
+    if (N < 1)
+        return;
+    // If the cursor is inactive, activate it
+    if (choice_ == INVALID)
+    {
+        if (delta > 0)
+        {
+            choice_ = 0;
+        }
+        else
+        {
+            choice_ = N - 1;
+        }
+        return;
+    }
+    const int nrows =
+        (order == ColumnMajor) ? DispEntriesPerColumn() : DispEntriesPerRow();
+    const int tot_columns = (N - 1) / nrows + 1;
+    const int num_rows_last_column = N - nrows * (tot_columns - 1);
+    int y = choice_ % nrows, x = choice_ / nrows;
+    if (delta == 1)
+    {
+        x++;
+    }
+    else
+    {
+        x--;
+    }
+    bool overflow_to_right = false;
+    if (y < num_rows_last_column && x >= tot_columns)
+    {
+        overflow_to_right = true;
+    }
+    if (y >= num_rows_last_column && x >= tot_columns - 1)
+    {
+        overflow_to_right = true;
+    }
+    bool overflow_to_left = false;
+    if (x < 0)
+    {
+        overflow_to_left = true;
+    }
+    if (overflow_to_right)
+    {
+        y++;
+        if (y >= nrows)
+        {
+            choice_ = 0;
+            return;
+        }
+        else
+        {
+            choice_ = y;
+            return;
+        }
+    }
+    else if (overflow_to_left)
+    {
+        y--;
+        if (y < 0)
+        {
+            if (num_rows_last_column == nrows)
+            {
+                choice_ = N - 1;
+            }
+            else
+            {
+                choice_ = N - num_rows_last_column - 1;
+            }
+            return;
+        }
+        else
+        {
+            if (y < num_rows_last_column)
+            {
+                choice_ = nrows * (tot_columns - 1) + y;
+            }
+            else
+            {
+                choice_ = nrows * (tot_columns - 2) + y;
+            }
+        }
+    }
+    else
+    {
+        choice_ = y + x * nrows;
+    }
+}
+
+void ArrowKeyNavigationMenu::SetChoiceAndConstrain(int c)
+{
+    if (Empty())
+    {
+        choice_ = INVALID;
+        return;
+    }
+    if (c < 0)
+        c = 0;
+    if (c >= static_cast<int>(items_.size()))
+    {
+        c = static_cast<int>(items_.size() - 1);
+    }
+    choice_ = c;
+}
+
+void ArrowKeyNavigationMenu::AddItem(const std::string& s)
+{
+    items_.push_back(s);
+}
+
+bool ArrowKeyNavigationMenu::RemoveHighlightedItem(std::string* ret)
+{
+    if (choice_ < 0 || choice_ >= items_.size())
+        return false;
+    std::string r = items_[choice_];
+    items_.erase(items_.begin() + choice_);
+    if (items_.empty())
+    {
+        Deselect();
+    }
+    else
+    {
+        if (choice_ >= items_.size())
+        {
+            choice_ = items_.size() - 1;
+        }
+    }
+    if (ret)
+    {
+        *ret = r;
+    }
+    return true;
+}
\ No newline at end of file
diff --git a/dbus-top/menu.hpp b/dbus-top/menu.hpp
new file mode 100644
index 0000000..afb4110
--- /dev/null
+++ b/dbus-top/menu.hpp
@@ -0,0 +1,122 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+#include "main.hpp"
+
+#include <ncurses.h>
+
+#include <string>
+#include <vector>
+class DBusTopWindow;
+class ArrowKeyNavigationMenu
+{
+  public:
+    explicit ArrowKeyNavigationMenu(WINDOW* win) :
+        win_(win), h_padding_(2), col_width_(15), h_spacing_(2), idx0_(INVALID),
+        idx1_(INVALID), choice_(INVALID), parent_(nullptr)
+    {}
+    explicit ArrowKeyNavigationMenu(DBusTopWindow* view);
+    void LoadDummyValues()
+    {
+        items_.clear();
+        items_.push_back("Sender");
+        items_.push_back("Destination");
+        items_.push_back("Interface");
+        items_.push_back("Path");
+        items_.push_back("Member");
+    }
+
+    void OnKeyDown(const std::string& key);
+    void Render();
+    void MoveCursorAlongSecondaryAxis(int delta);
+    void MoveCursorAlongPrimaryAxis(int delta);
+    int DispEntriesPerRow()
+    {
+        int ncols = 0;
+        while (true)
+        {
+            int next = ncols + 1;
+            int w = 2 * h_padding_ + col_width_ * next;
+            if (next > 1)
+                w += (next - 1) * h_spacing_;
+            if (w <= rect_.w - 2)
+            {
+                ncols = next;
+            }
+            else
+            {
+                break;
+            }
+        }
+        return ncols;
+    }
+
+    int DispEntriesPerColumn()
+    {
+        return rect_.h;
+    }
+
+    void SetRect(const Rect& rect)
+    {
+        rect_ = rect;
+    }
+
+    enum Order
+    {
+        ColumnMajor,
+        RowMajor,
+    };
+
+    void SetOrder(Order o)
+    {
+        order = o;
+    }
+
+    int Choice()
+    {
+        return choice_;
+    }
+
+    void Deselect()
+    {
+        choice_ = INVALID;
+    }
+
+    bool Empty()
+    {
+        return items_.empty();
+    }
+
+    void SetChoiceAndConstrain(int c);
+    Rect rect_;
+    void AddItem(const std::string& s);
+    bool RemoveHighlightedItem(std::string* ret); // returns true if successful
+    std::vector<std::string> Items()
+    {
+        return items_;
+    }
+
+    void do_Render(bool is_column_major);
+    std::vector<std::string> items_;
+    WINDOW* win_;
+    int h_padding_;
+    int col_width_;
+    int h_spacing_;
+    int idx0_, idx1_;
+    int choice_;
+    DBusTopWindow* parent_;
+    Order order;
+};
+
diff --git a/dbus-top/meson.build b/dbus-top/meson.build
new file mode 100644
index 0000000..60d4641
--- /dev/null
+++ b/dbus-top/meson.build
@@ -0,0 +1,48 @@
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project('dbus-top', 'cpp',
+    version: '0.1',
+    default_options: 
+    [
+        'cpp_std=c++17',
+    ],
+)
+
+cmake = import('cmake')
+fmt_proj = cmake.subproject('fmt')
+fmt_dep = fmt_proj.dependency('fmt')
+
+bindir = get_option('prefix') / get_option('bindir')
+executable('dbus-top',
+    [
+        'menu.cpp',
+        'analyzer.cpp',
+        'dbus_capture.cpp',
+        'sensorhelper.cpp',
+        'xmlparse.cpp',
+        'views.cpp',
+        'main.cpp',
+    ],
+    dependencies:
+    [
+        dependency('systemd'),
+        dependency('sdbusplus'),
+        dependency('ncurses'),
+        dependency('threads'),
+        fmt_dep
+    ],
+    install: true,
+    install_dir: bindir
+)
diff --git a/dbus-top/rect.hpp b/dbus-top/rect.hpp
new file mode 100644
index 0000000..aa7bf89
--- /dev/null
+++ b/dbus-top/rect.hpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+struct Rect
+{
+    int x, y, w, h; // X, Y, Width, Height
+    Rect(int _x, int _y, int _w, int _h) : x(_x), y(_y), w(_w), h(_h)
+    {}
+    Rect() : x(0), y(0), w(1), h(1)
+    {}
+};
\ No newline at end of file
diff --git a/dbus-top/sensorhelper.cpp b/dbus-top/sensorhelper.cpp
new file mode 100644
index 0000000..3f8bba6
--- /dev/null
+++ b/dbus-top/sensorhelper.cpp
@@ -0,0 +1,130 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "sensorhelper.hpp"
+#include "main.hpp"
+
+#include <unistd.h>
+
+#include <cassert>
+#include <fstream>
+#include <functional>
+#include <sstream>
+#include <string>
+#include <vector>
+
+extern SensorSnapshot* g_sensor_snapshot;
+extern DBusConnectionSnapshot* g_connection_snapshot;
+
+std::vector<std::string> MySplit(const std::string& s)
+{
+    int idx = 0, prev_idx = 0;
+    std::vector<std::string> ret;
+    while (idx <= static_cast<int>(s.size()))
+    {
+        if (idx == static_cast<int>(s.size()) || s[idx] == '/')
+        {
+            if (idx > prev_idx)
+            {
+                ret.push_back(s.substr(prev_idx, idx - prev_idx));
+            }
+            prev_idx = idx + 1;
+        }
+        idx++;
+    }
+    return ret;
+}
+
+// Example: /xyz/openbmc_project/sensors/temperature/powerseq_temp
+bool IsSensorObjectPath(const std::string& s)
+{
+    std::vector<std::string> sections = MySplit(s);
+    if (sections.size() == 5 && sections[0] == "xyz" &&
+        sections[1] == "openbmc_project" && sections[2] == "sensors")
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+// Example: /xyz/openbmc_project/sensors/temperature/powerseq_temp/chassis
+bool IsSensorObjectPathWithAssociation(const std::string& s,
+                                       std::string* sensor_obj_path)
+{
+    std::vector<std::string> sections = MySplit(s);
+    if (sections.size() == 6)
+    {
+        size_t idx = s.rfind('/');
+        return IsSensorObjectPath(s.substr(0, idx));
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool IsUniqueName(const std::string& x)
+{
+    if (x.empty())
+        return false;
+    if (x[0] != ':')
+        return false;
+    if (x[0] == ':')
+    {
+        for (int i = 1; i < int(x.size()); i++)
+        {
+            const char ch = x[i];
+            if (ch >= '0' || ch <= '9')
+                continue;
+            else if (ch == '.')
+                continue;
+            else
+                return false;
+        }
+    }
+    return true;
+}
+
+std::vector<std::string> FindAllObjectPathsForService(
+    const std::string& service,
+    std::function<void(const std::string&, const std::vector<std::string>&)>
+        on_interface_cb)
+{
+    // Not available for PCAP replay, only valid with actual DBus capture
+    assert(false);
+}
+
+bool IsWhitespace(const char c)
+{
+    if (c == ' ' || c == '\r' || c == '\n')
+        return true;
+    else
+        return false;
+}
+
+std::string Trim(const std::string& s)
+{
+    const int N = int(s.size());
+    int idx0 = 0, idx1 = int(N - 1);
+    while (idx0 < N && IsWhitespace(s[idx0]))
+        idx0++;
+    while (idx1 >= 0 && IsWhitespace(s[idx1]))
+        idx1--;
+    if (idx0 >= N || idx1 < 0)
+        return "";
+    return s.substr(idx0, idx1 - idx0 + 1);
+}
diff --git a/dbus-top/sensorhelper.hpp b/dbus-top/sensorhelper.hpp
new file mode 100644
index 0000000..a619c4a
--- /dev/null
+++ b/dbus-top/sensorhelper.hpp
@@ -0,0 +1,342 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include "main.hpp"
+// This is the form a sensor assumes on DBus.
+// Aggregates their view from all other daemons.
+#include <bitset>
+#include <optional>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+// Where is this sensor seen?
+constexpr int VISIBILITY_OBJECT_MAPPER = 0;
+constexpr int VISIBILITY_HWMON = 1;
+constexpr int VISIBILITY_IPMITOOL_SDR = 2;
+class DBusConnection
+{
+  public:
+    std::string service;    // example: "systemd-resolved"
+    std::string connection; // example: ":1.1"
+    std::string cmd;        // the comm line
+    std::string unit;       // example: "systemd-resolved.service"
+    int pid;
+    // For actual DBus capture: service name, connection name, command line,
+    //                          systmed unit and PID are all known
+    DBusConnection(const std::string& _s, const std::string& _c,
+                   const std::string& _cmd, const std::string& _u, int _pid)
+    {
+        service = _s;
+        connection = _c;
+        cmd = _cmd;
+        unit = _u;
+        pid = _pid;
+    }
+
+    // During PCap replay: only service name, connection name, and PID are known
+    //                     cmd and unit are not known since they are not
+    //                     stored in the PCap file
+    DBusConnection(const std::string& _s, const std::string& _c, int _pid)
+    {
+        service = _s;
+        connection = _c;
+        pid = _pid;
+    }
+};
+
+class DBusConnectionSnapshot
+{
+  public:
+    std::vector<DBusConnection*> connections_;
+    std::unordered_map<std::string, DBusConnection*> unique_name_to_cxn;
+    DBusConnection* FindDBusConnectionByService(const std::string& service)
+    {
+        for (DBusConnection* cxn : connections_)
+        {
+            if (cxn->service == service)
+                return cxn;
+        }
+        return nullptr;
+    }
+
+    void SetConnectionPID(const std::string& connection, int pid)
+    {
+        DBusConnection* cxn = FindDBusConnectionByService(connection);
+        if (cxn != nullptr)
+        {
+            cxn->pid = pid;
+            unique_name_to_cxn[connection] = cxn; // Just to make sure
+        }
+    }
+
+    void SetConnectionUniqueName(const std::string& service,
+                                 const std::string& unique_name)
+    {
+        DBusConnection* cxn = FindDBusConnectionByService(service);
+        if (cxn != nullptr)
+        {
+            cxn->connection = unique_name;
+            unique_name_to_cxn[unique_name] = cxn;
+        }
+    }
+
+    DBusConnection* FindDBusConnectionByConnection(const std::string& conn)
+    {
+        for (DBusConnection* cxn : connections_)
+        {
+            if (cxn->connection == conn)
+                return cxn;
+        }
+        return nullptr;
+    }
+
+
+    // Only when service is known (during playback)
+    void AddConnection(const std::string& _s)
+    {
+        connections_.push_back(new DBusConnection(_s, "", "", "", INVALID));
+    }
+
+    // When all 5 pieces of details are known (during actual capture)
+    void AddConnection(const std::string& _s, const std::string& _connection,
+                       const std::string& _cmd, const std::string& _unit,
+                       int _pid)
+    {
+        DBusConnection* cxn =
+            new DBusConnection(_s, _connection, _cmd, _unit, _pid);
+        connections_.push_back(cxn);
+        unique_name_to_cxn[_connection] = cxn;
+    }
+
+    int GetConnectionPIDFromNameOrUniqueName(const std::string& key)
+    {
+        if (unique_name_to_cxn.find(key) == unique_name_to_cxn.end())
+        {
+            return INVALID;
+        }
+        else
+        {
+            return unique_name_to_cxn[key]->pid;
+        }
+    }
+
+    std::string GetConnectionCMDFromNameOrUniqueName(const std::string& key)
+    {
+        if (unique_name_to_cxn.find(key) == unique_name_to_cxn.end())
+        {
+            return "(unknown)";
+        }
+        else
+        {
+            return unique_name_to_cxn[key]->cmd;
+        }
+    }
+
+    std::string GetUniqueNameIfExists(const std::string service)
+    {
+        for (DBusConnection* cxn : connections_)
+        {
+            if (cxn->service == service)
+                return cxn->connection;
+        }
+        return service;
+    }
+
+};
+
+// Each sensor might have different units, for example current and voltage
+class Sensor
+{
+  public:
+    DBusConnection* connection_;
+    // Example: "/xyz/openbmc_project/sensors/temperature/powerseq_temp"
+    std::string object_path_;
+    std::string SensorID()
+    {
+        const size_t idx = object_path_.rfind('/');
+        if (idx != std::string::npos)
+        {
+            return object_path_.substr(idx + 1);
+        }
+        else
+            return ("unknown sensor");
+    }
+
+    std::string ServiceName()
+    {
+        if (connection_ == nullptr)
+            return "";
+        else
+            return connection_->service;
+    }
+
+    std::string ConnectionName()
+    {
+        if (connection_ == nullptr)
+            return "";
+        else
+            return connection_->connection;
+    }
+
+    std::string ObjectPath()
+    {
+        return object_path_;
+    }
+
+    // Should contain the following:
+    // 1. "org.freedesktop.DBus.Introspectable"
+    // 2. "org.freedesktop.DBus.Peer"
+    // 3. "org.freedesktop.DBus.Properties"
+    // 4. "xyz.openbmc_project.Sensor.Value"
+    // 5. "xyz.openbmc_project.State.Decorator.OperationalStatus"
+    std::set<std::string> interfaces_;
+    std::bitset<4> visibility_flags_;
+    std::set<std::string> associations_;
+};
+
+class SensorSnapshot
+{
+  public:
+    std::vector<std::string> GetDistinctSensorNames()
+    {
+        std::unordered_set<std::string> seen;
+        std::vector<std::string> ret;
+        for (Sensor* s : sensors_)
+        {
+            std::string sn = s->SensorID();
+            if (seen.find(sn) == seen.end())
+            {
+                ret.push_back(sn);
+                seen.insert(sn);
+            }
+        }
+        return ret;
+    }
+
+    explicit SensorSnapshot(DBusConnectionSnapshot* cs)
+    {
+        connection_snapshot_ = cs;
+    }
+
+    ~SensorSnapshot()
+    {
+        for (Sensor* s : sensors_)
+        {
+            delete s;
+        }
+    }
+
+    int SensorCount()
+    {
+        return int(sensors_.size());
+    }
+
+    Sensor* FindOrCreateSensorByServiceAndObject(const std::string& service,
+                                                 const std::string& object)
+    {
+        Sensor* ret = nullptr;
+        for (Sensor* s : sensors_)
+        {
+            if (s->ServiceName() == service && s->object_path_ == object)
+            {
+                ret = s;
+                break;
+            }
+        }
+        if (ret == nullptr)
+        {
+            DBusConnection* cxn =
+                connection_snapshot_->FindDBusConnectionByService(service);
+            ret = new Sensor();
+            ret->connection_ = cxn;
+            ret->object_path_ = object;
+            sensors_.push_back(ret);
+        }
+        return ret;
+    }
+
+    // Note: one sensor_id might correspond to multiple sensors.
+    // Example: "VDD" can have all 3 of power, current and voltage.
+    std::vector<Sensor*> FindSensorsBySensorID(const std::string& sensor_id)
+    {
+        std::vector<Sensor*> ret;
+        for (Sensor* s : sensors_)
+        {
+            const std::string& p = s->object_path_;
+            if (p.find(sensor_id) == p.size() - sensor_id.size())
+            {
+                ret.push_back(s);
+            }
+        }
+        return ret;
+    }
+
+    // This sensor is visible from Object Mapper
+    void SerSensorVisibleFromObjectMapper(const std::string& service,
+                                          const std::string& object)
+    {
+        Sensor* s = FindOrCreateSensorByServiceAndObject(service, object);
+        s->visibility_flags_.set(VISIBILITY_OBJECT_MAPPER);
+    }
+    
+    // This sensor is visible from Hwmon
+    void SetSensorVisibleFromHwmon(const std::string& service,
+                                   const std::string& object)
+    {
+        Sensor* s = FindOrCreateSensorByServiceAndObject(service, object);
+        s->visibility_flags_.set(VISIBILITY_HWMON);
+    }
+
+    // This sensor is visible from `ipmitool sdr`
+    // The first column is referred to as "sensorid".
+    void SetSensorVisibleFromIpmitoolSdr(const std::string& sensor_id)
+    {
+        std::vector<Sensor*> sensors = FindSensorsBySensorID(sensor_id);
+        for (Sensor* s : sensors)
+            s->visibility_flags_.set(VISIBILITY_IPMITOOL_SDR);
+    }
+
+    void PrintSummary()
+    {
+        for (Sensor* s : sensors_)
+        {
+            printf("%50s %50s %9s\n", s->ServiceName().c_str(),
+                   s->object_path_.c_str(),
+                   s->visibility_flags_.to_string().c_str());
+        }
+    }
+
+    Sensor* FindSensorByDBusUniqueNameOrServiceName(const std::string& key)
+    {
+        for (Sensor* s : sensors_)
+        {
+            if (s->ConnectionName() == key || s->ServiceName() == key)
+                return s;
+        }
+        return nullptr;
+    }
+
+  private:
+    std::vector<Sensor*> sensors_;
+    std::unordered_map<std::string, int> conn2pid_;
+    DBusConnectionSnapshot* connection_snapshot_;
+};
+
+bool IsSensorObjectPath(const std::string& s);
+bool IsUniqueName(const std::string& x);
+std::string Trim(const std::string& s);
diff --git a/dbus-top/subprojects/fmt.wrap b/dbus-top/subprojects/fmt.wrap
new file mode 100644
index 0000000..6847ae5
--- /dev/null
+++ b/dbus-top/subprojects/fmt.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/fmtlib/fmt
+revision = HEAD
diff --git a/dbus-top/subprojects/sdbusplus.wrap b/dbus-top/subprojects/sdbusplus.wrap
new file mode 100644
index 0000000..7b076d0
--- /dev/null
+++ b/dbus-top/subprojects/sdbusplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdbusplus.git
+revision = HEAD
+
+[provide]
+sdbusplus = sdbusplus_dep
diff --git a/dbus-top/views.cpp b/dbus-top/views.cpp
new file mode 100644
index 0000000..0e6f8b0
--- /dev/null
+++ b/dbus-top/views.cpp
@@ -0,0 +1,1236 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "views.hpp"
+#include "bargraph.hpp"
+#include "histogram.hpp"
+#include "menu.hpp"
+#include <string.h>
+#include <algorithm>
+
+extern SensorSnapshot* g_sensor_snapshot;
+extern BarGraph<float>* g_bargraph;
+extern DBusTopStatistics* g_dbus_statistics;
+extern Histogram<float>* g_histogram;
+extern DBusTopWindow* g_current_active_view;
+extern const std::string FieldNames[];
+extern const int FieldPreferredWidths[];
+
+namespace dbus_top_analyzer
+{
+    extern DBusTopStatistics g_dbus_statistics;
+}
+
+// Linear interpolation
+float Lerp(float a, float b, float t)
+{
+    return a + t * (b - a);
+}
+
+// Linear map
+float Map(float value, float start1, float stop1, float start2, float stop2,
+          bool within_bounds)
+{
+    float t = (value - start1) / (stop1 - start1);
+    float ret = Lerp(start2, stop2, t);
+    if (within_bounds)
+    {
+        if (ret < start2)
+            ret = start2;
+        if (ret > stop2)
+            ret = stop2;
+    }
+    return ret;
+}
+
+template <typename T>
+void HistoryBarGraph(WINDOW* win, const Rect& rect, BarGraph<T>* bargraph)
+{
+    const int RIGHT_MARGIN = 5;
+    const int x0 = rect.x, y0 = 2;
+    const int w = rect.w - 2 - RIGHT_MARGIN;
+    const int h = rect.h - 3; // height of content
+    wattrset(win, 0);
+    wattron(win, A_BOLD | A_UNDERLINE);
+    mvwaddstr(win, 1, x0, "History     (Total msg/s)");
+    wattrset(win, 0);
+    // 1. Obtain data, determine Y range
+    std::vector<float> data = bargraph->GetLastNValues(w - RIGHT_MARGIN - 1);
+    float ymax = -1e20, ymin = 1e20;
+    if (data.empty())
+    {
+        data.push_back(0);
+        ymin = 0;
+        ymax = 10;
+    }
+    else
+    {
+        for (const float x : data)
+        {
+            ymax = std::max(ymax, x);
+            ymin = std::min(ymin, x);
+        }
+    }
+    // Fix edge case for both == 0
+    float diff = ymax - ymin;
+    if (diff < 0)
+    {
+        diff = -diff;
+    }
+    const float EPS = 1e-4;
+    if (diff < EPS)
+    {
+        ymax += 10;
+        ymin -= 10;
+    }
+    // Choose a suitable round-up unit to snap the grid labels to
+    int snap = 1;
+    if (ymax < 100)
+    {
+        snap = 10;
+    }
+    else if (ymax < 10000)
+    {
+        snap = 100;
+    }
+    else
+    {
+        snap = 1000;
+    }
+    const float eps = snap / 100.0f;
+    int label_ymax =
+        (static_cast<int>((ymax - eps) / snap) + 1) * snap; // round up
+    int label_ymin = static_cast<int>(ymin / snap) * snap;  // round down
+    float y_per_row = (label_ymax - label_ymin) * 1.0f / (h - 1);
+    int actual_ymax = label_ymax + static_cast<int>(y_per_row / 2);
+    int actual_ymin = label_ymin - static_cast<int>(y_per_row / 2);
+    // 2. Print Y axis ticks
+    for (int i = 0; i < h; i++)
+    {
+        char buf[10];
+        snprintf(
+            buf, sizeof(buf), "%-6d",
+            static_cast<int>(Lerp(label_ymax, label_ymin, i * 1.0f / (h - 1))));
+        mvwaddstr(win, i + y0, x0 + w - RIGHT_MARGIN + 1, buf);
+        mvwaddch(win, i + y0, x0, '-');
+        mvwaddch(win, i + y0, x0 + w - RIGHT_MARGIN, '-');
+    }
+    // 3. Go through the historical data and draw on the canvas
+    for (int i = 0;
+         i < std::min(static_cast<int>(data.size()), w - RIGHT_MARGIN - 1); i++)
+    {
+        float value = data[i];
+        // antialiasing: todo for now
+        // float value1 = value; // value1 is 1 column to the right
+        // if (i > 0) value1 = data[i-1];
+        int x = x0 + w - i - RIGHT_MARGIN - 1;
+        float t = Map(value, actual_ymin, actual_ymax, 0, h, true);
+        int row = static_cast<int>(t);
+        float remaining = t - row;
+        char ch; // Last filling character
+        if (remaining >= 0.66f)
+        {
+            ch = ':';
+        }
+        else if (remaining >= 0.33f)
+        {
+            ch = '.';
+        }
+        else
+        {
+            ch = ' ';
+        }
+        int y = y0 + h - row - 1;
+        mvwaddch(win, y, x, ch);
+        for (int j = 0; j < row; j++)
+        {
+            mvwaddch(win, y + j + 1, x, ':');
+        }
+    }
+}
+
+template <typename T>
+void DrawHistogram(WINDOW* win, const Rect& rect, Histogram<T>* histogram)
+{
+    // const int MARGIN = 7;  // 5 digits margin
+    const int LEFT_MARGIN = 7;
+    // const int max_bucket_h = histogram->MaxBucketHeight();
+    const int H_PAD = 0, V_PAD = 1;
+    // x0, x1, y0 and y1 are the bounding box of the contents to be printed
+    const int x0 = rect.x + H_PAD;
+    const int x1 = rect.x + rect.w - H_PAD;
+    const int y0 = rect.y + V_PAD;
+    const int y1 = rect.y + rect.h - 1 - V_PAD;
+    // Title
+    wattron(win, A_BOLD | A_UNDERLINE);
+    mvwaddstr(win, y0, x0, "Method Call Time (us) Histogram");
+    wattrset(win, 0);
+    // x2 is the beginning X of the histogram itself (not containing the margin)
+    const int x2 = x0 + LEFT_MARGIN;
+    if (histogram->Empty())
+    {
+        mvwaddstr(win, (y1 + y0) / 2, (x0 + x1) / 2, "(Empty)");
+        return;
+    }
+    histogram->SetBucketCount(x1 - x2 + 1);
+    histogram->ComputeHistogram();
+    // Draw X axis labels
+    char buf[22];
+    snprintf(buf, sizeof(buf), "%.2f",
+             static_cast<float>(histogram->LowPercentile()));
+    mvwaddstr(win, y1, x0 + LEFT_MARGIN, buf);
+    snprintf(buf, sizeof(buf), "%.2f",
+             static_cast<float>(histogram->HighPercentile()));
+    mvwaddstr(win, y1, x1 + 1 - strlen(buf), buf);
+    snprintf(buf, sizeof(buf), "%d%%-%d%%",
+             static_cast<int>(histogram->LowCumDensity() * 100),
+             static_cast<int>(histogram->HighCumDensity() * 100));
+    mvwaddstr(win, y1, x0, buf);
+    // Draw Y axis labels
+    const float hist_ymax = y1 - 1;
+    const float hist_ymin = y0 + 1;
+    const int max_histogram_h = histogram->MaxBucketHeight();
+    if (hist_ymax <= hist_ymin)
+        return; // Not enough space for rendering
+    if (max_histogram_h <= 0)
+        return;
+    bool LOG_TRANSFORM = true;
+    float lg_maxh = 0;
+    if (LOG_TRANSFORM)
+    {
+        lg_maxh = log(max_histogram_h);
+    }
+    for (int y = hist_ymin; y <= hist_ymax; y++)
+    {
+        // There are (hist_ymax - hist_ymin + 1) divisions
+        float fullness;
+        fullness = (hist_ymax - y + 1) * 1.0f / (hist_ymax - hist_ymin + 1);
+        int h;
+        if (!LOG_TRANSFORM)
+        {
+            h = static_cast<int>(max_histogram_h * fullness);
+        }
+        else
+        {
+            h = static_cast<int>(exp(fullness * lg_maxh));
+        }
+        snprintf(buf, sizeof(buf), "%6d-", h);
+        mvwaddstr(win, y, x0 + LEFT_MARGIN - strlen(buf), buf);
+    }
+    const int bar_height = hist_ymax - hist_ymin + 1; // Height of a full bar
+    for (int x = x2, bidx = 0; x <= x1; x++, bidx++)
+    {
+        int h = histogram->BucketHeight(bidx);
+        float lines_visible;
+        if (!LOG_TRANSFORM)
+        {
+            lines_visible = h * 1.0f / max_histogram_h * bar_height;
+        }
+        else
+        {
+            if (h <= 0)
+                lines_visible = 0;
+            else
+                lines_visible = log(h) * 1.0f / lg_maxh * bar_height;
+        }
+        // The histogram's top shall start from this line
+        int y = hist_ymax - static_cast<int>(lines_visible);
+        float y_frac = lines_visible - static_cast<int>(lines_visible);
+        char ch; // Last filling character
+        if (y >= hist_ymin)
+        { // At the maximum bucket the Y overflows, so skip
+            if (y_frac >= 0.66f)
+            {
+                ch = ':';
+            }
+            else if (y_frac >= 0.33f)
+            {
+                ch = '.';
+            }
+            else
+            {
+                if (y < hist_ymax)
+                {
+                    ch = ' ';
+                }
+                else
+                {
+                    if (y_frac > 0)
+                    {
+                        ch =
+                            '.'; // Makes long-tailed distribution easier to see
+                    }
+                }
+            }
+            mvwaddch(win, y, x, ch);
+        }
+        y++;
+        for (; y <= hist_ymax; y++)
+        {
+            mvwaddch(win, y, x, ':');
+        }
+    }
+}
+
+void SummaryView::UpdateDBusTopStatistics(DBusTopStatistics* stat)
+{
+    if (!stat)
+        return;
+    float interval_secs = stat->seconds_since_last_sample_;
+    if (interval_secs == 0)
+    {
+        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
+    }
+    // Per-second
+    method_call_ = stat->num_mc_ / interval_secs;
+    method_return_ = stat->num_mr_ / interval_secs;
+    signal_ = stat->num_sig_ / interval_secs;
+    error_ = stat->num_error_ / interval_secs;
+    total_ = stat->num_messages_ / interval_secs;
+    g_bargraph->AddValue(total_);
+}
+
+std::string Ellipsize(const std::string& s, int len_limit)
+{
+    if (len_limit <= 3)
+        return s.substr(0, len_limit);
+    if (static_cast<int>(s.size()) < len_limit)
+    {
+        return s;
+    }
+    else
+    {
+        return s.substr(0, len_limit - 3) + "...";
+    }
+}
+
+void SummaryView::Render()
+{
+    // Draw text
+    werase(win);
+    if (!visible_)
+        return;
+    wattron(win, A_BOLD | A_UNDERLINE);
+    mvwaddstr(win, 1, 1, "Message Type          | msg/s");
+    wattrset(win, 0);
+    const int xend = 30;
+    std::string s;
+    s = FloatToString(method_call_);
+    mvwaddstr(win, 2, 1, "Method Call");
+    mvwaddstr(win, 2, xend - s.size(), s.c_str());
+    s = FloatToString(method_return_);
+    mvwaddstr(win, 3, 1, "Method Return ");
+    mvwaddstr(win, 3, xend - s.size(), s.c_str());
+    s = FloatToString(signal_);
+    mvwaddstr(win, 4, 1, "Signal");
+    mvwaddstr(win, 4, xend - s.size(), s.c_str());
+    s = FloatToString(error_);
+    mvwaddstr(win, 5, 1, "Error ");
+    mvwaddstr(win, 5, xend - s.size(), s.c_str());
+    wattron(win, A_UNDERLINE);
+    s = FloatToString(total_);
+    mvwaddstr(win, 6, 1, "Total");
+    mvwaddstr(win, 6, xend - s.size(), s.c_str());
+    wattroff(win, A_UNDERLINE);
+    wattrset(win, 0);
+    // Draw history bar graph
+    Rect bargraph_rect = rect;
+    const int bargraph_x = 64;
+    bargraph_rect.x += bargraph_x;
+    bargraph_rect.w -= bargraph_x;
+    HistoryBarGraph(win, bargraph_rect, g_bargraph);
+    // Draw histogram
+    Rect histogram_rect = rect;
+    histogram_rect.x += 32;
+    histogram_rect.w = bargraph_rect.x - histogram_rect.x - 3;
+    DrawHistogram(win, histogram_rect, g_histogram);
+    // Draw border between summary and histogram
+    for (int y = bargraph_rect.y; y <= bargraph_rect.y + bargraph_rect.h; y++)
+    {
+        mvwaddch(win, y, histogram_rect.x - 1, '|');
+        mvwaddch(win, y, bargraph_rect.x - 1, '|');
+    }
+    DrawBorderIfNeeded();
+    wrefresh(win);
+}
+
+void SensorDetailView::Render()
+{
+    werase(win);
+    if (!visible_)
+        return;
+    // If some sensor is focused, show details regarding that sensor
+    if (state == SensorList)
+    { // Otherwise show the complete list
+        const int ncols = DispSensorsPerRow(); // Number of columns in viewport
+        const int nrows = DispSensorsPerColumn(); // # rows in viewport
+        int sensors_per_page = nrows * ncols;
+        // Just in case the window gets invisibly small
+        if (sensors_per_page < 1)
+            return;
+        int num_sensors = sensor_ids_.size();
+        int total_num_columns = (num_sensors - 1) / nrows + 1;
+        bool is_cursor_out_of_view = false;
+        if (idx0 > choice_ || idx1 <= choice_)
+        {
+            is_cursor_out_of_view = true;
+        }
+        if (idx0 == INVALID || idx1 == INVALID)
+        {
+            is_cursor_out_of_view = true;
+        }
+        if (is_cursor_out_of_view)
+        {
+            idx0 = 0, idx1 = sensors_per_page;
+        }
+        while (idx1 <= choice_)
+        {
+            idx0 += nrows;
+            idx1 += nrows;
+        }
+        const int y0 = 2; // to account for the border and info line
+        const int x0 = 4; // to account for the left overflow marks
+        int y = y0, x = x0;
+        for (int i = 0; i < sensors_per_page; i++)
+        {
+            int idx = idx0 + i;
+            if (idx < static_cast<int>(sensor_ids_.size()))
+            {
+                if (idx == choice_)
+                {
+                    wattrset(win, A_REVERSE);
+                }
+                std::string s = sensor_ids_[idx];
+                if (static_cast<int>(s.size()) > col_width) {
+                    s = s.substr(0, col_width - 2) + "..";
+                } else {
+                    while (static_cast<int>(s.size()) < col_width)
+                    {
+                        s.push_back(' ');
+                    }
+                }
+                mvwprintw(win, y, x, s.c_str());
+                wattrset(win, 0);
+            }
+            else
+                break;
+            y++;
+            if (i % nrows == nrows - 1)
+            {
+                y = y0;
+                x += col_width + h_spacing;
+            }
+        }
+        // Print overflow marks to the right of the screen
+        for (int i = 0; i < nrows; i++)
+        {
+            int idx = idx0 + sensors_per_page + i;
+            if (idx < num_sensors)
+            {
+                mvwaddch(win, y0 + i, x, '>');
+            }
+        }
+        // Print overflow marks to the left of the screen
+        for (int i = 0; i < nrows; i++)
+        {
+            int idx = idx0 - nrows + i;
+            if (idx >= 0)
+            {
+                mvwaddch(win, y0 + i, 2, '<');
+            }
+        }
+        // idx1 is one past the visible range, so no need to +1
+        const int col0 = idx0 / nrows + 1, col1 = idx1 / nrows;
+        mvwprintw(win, 1, 2, "Columns %d-%d of %d", col0, col1,
+                  total_num_columns);
+        mvwprintw(win, 1, rect.w - 15, "%d sensors", sensor_ids_.size());
+    }
+    else if (state == SensorDetail)
+    {
+        // sensor_ids_ is the cached list of sensors, it should be the same size
+        // as the actual number of sensors in the snapshot
+        mvwprintw(win, 1, 2, "Details of sensor %s", curr_sensor_id_.c_str());
+        mvwprintw(win, 1, rect.w - 15, "Sensor %d/%u", choice_ + 1,
+                  sensor_ids_.size()); // 1-based
+        std::vector<Sensor*> sensors =
+            g_sensor_snapshot->FindSensorsBySensorID(curr_sensor_id_);
+        const int N = static_cast<int>(sensors.size());
+        const int w = rect.w - 5;
+        mvwprintw(win, 3, 2, "There are %d sensors with the name %s", N,
+                  curr_sensor_id_.c_str());
+        int y = 5;
+        int x = 2;
+        if (N > 0)
+        {
+            for (int j = 0; j < N; j++)
+            {
+                Sensor* sensor = sensors[j];
+                mvwprintw(win, y, x, "%d/%d", j + 1, N);
+                char buf[200];
+                snprintf(buf, sizeof(buf), "DBus Service    : %s",
+                         sensor->ServiceName().c_str());
+                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
+                snprintf(buf, sizeof(buf), "DBus Connection : %s",
+                         sensor->ConnectionName().c_str());
+                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
+                snprintf(buf, sizeof(buf), "DBus Object Path: %s",
+                         sensor->ObjectPath().c_str());
+                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
+                y++;
+            }
+        }
+        else
+        {
+            mvwprintw(win, y, x, "Sensor details not found");
+        }
+    }
+    DrawBorderIfNeeded();
+    wrefresh(win);
+}
+
+std::string SensorDetailView::GetStatusString()
+{
+    if (state == SensorList)
+    {
+        return "[Arrow Keys]=Move Cursor [Q]=Deselect [Enter]=Show Sensor "
+               "Detail";
+    }
+    else
+    {
+        return "[Arrow Keys]=Cycle Through Sensors [Esc/Q]=Exit";
+    }
+}
+
+DBusStatListView::DBusStatListView() : DBusTopWindow()
+{
+    highlight_col_idx_ = 0;
+    sort_col_idx_ = 0;
+    sort_order_ = SortOrder::Ascending;
+    horizontal_pan_ = 0;
+    row_idx_ = INVALID;
+    disp_row_idx_ = 0;
+    horizontal_pan_ = 0;
+    menu1_ = new ArrowKeyNavigationMenu(this);
+    menu2_ = new ArrowKeyNavigationMenu(this);
+    // Load all available field names
+    std::set<std::string> inactive_fields;
+    std::set<std::string> active_fields;
+
+    // Default choice of field names
+    const int N = static_cast<int>(sizeof(FieldNames) / sizeof(FieldNames[0]));
+    for (int i = 0; i < N; i++)
+    {
+        inactive_fields.insert(FieldNames[i]);
+    }
+    for (const std::string& s :
+         dbus_top_analyzer::g_dbus_statistics.GetFieldNames())
+    {
+        inactive_fields.erase(s);
+        active_fields.insert(s);
+    }
+    for (int i = 0; i < N; i++)
+    {
+    const std::string s = FieldNames[i];
+        if (inactive_fields.count(s) > 0)
+        {
+            menu1_->AddItem(s);
+        }
+        else
+        {
+            menu2_->AddItem(s);
+        }
+    }
+    
+    curr_menu_state_ = LeftSide;
+    menu_h_ = 5;
+    menu_w_ = 24; // Need at least 2*padding + 15 for enough space, see menu.hpp
+    menu_margin_ = 6;
+    // Populate preferred column widths
+    for (int i = 0; i < N; i++)
+    {
+        column_widths_[FieldNames[i]] = FieldPreferredWidths[i];
+    }
+}
+
+std::pair<int, int> DBusStatListView::GetXSpanForColumn(const int col_idx)
+{
+    std::vector<int> cw = ColumnWidths();
+    if (col_idx < 0 || col_idx >= static_cast<int>(cw.size()))
+    {
+        return std::make_pair(INVALID, INVALID);
+    }
+    int x0 = 0, x1 = 0;
+    for (int i = 0; i < col_idx; i++)
+    {
+        if (i > 0)
+        {
+            x0 += cw[i];
+        }
+    }
+    x1 = x0 + cw[col_idx] - 1;
+    return std::make_pair(x0, x1);
+}
+
+// If tolerance > 0, consider overlap before 2 intervals intersect
+// If tolerance ==0, consider overlap if 2 intervals exactly intersect
+// If tolerance < 0, consider overlap if Minimal Translate Distance is >=
+// -threshold
+bool IsSpansOverlap(const std::pair<int, int>& s0,
+                    const std::pair<int, int>& s1, int tolerance)
+{
+    if (tolerance >= 0)
+    {
+        if (s0.second < s1.first - tolerance)
+            return false;
+        else if (s1.second < s0.first - tolerance)
+            return false;
+        else
+            return true;
+    }
+    else
+    {
+        // Compute overlapping distance
+        std::vector<std::pair<int, int>> tmp(
+            4); // [x, 1] means the start of interval
+                // [x,-1] means the end of interval
+        tmp[0] = std::make_pair(s0.first, 1);
+        tmp[1] = std::make_pair(s0.second, -1);
+        tmp[2] = std::make_pair(s1.first, 1);
+        tmp[3] = std::make_pair(s1.second, -1);
+        std::sort(tmp.begin(), tmp.end());
+        int overlap_x0 = -INVALID, overlap_x1 = -INVALID;
+        int idx = 0;
+        const int N = static_cast<int>(tmp.size());
+        int level = 0;
+        while (idx < N)
+        {
+            const int x = tmp[idx].first;
+            while (idx < N && x == tmp[idx].first)
+            {
+                level += tmp[idx].second;
+                idx++;
+            }
+            // The starting position of the overlap
+            if (level == 2)
+            {
+                overlap_x0 = idx - 1;
+            }
+            // The ending position of the overlap
+            if (overlap_x0 != -INVALID && level < 2 && overlap_x1 == -INVALID)
+            {
+                overlap_x1 = idx - 1;
+            }
+        }
+        const int overlap_length = overlap_x1 - overlap_x0 + 1;
+        if (overlap_length >= -tolerance)
+            return true;
+        else
+            return false;
+    }
+}
+
+bool DBusStatListView::IsXSpanVisible(const std::pair<int, int>& xs,
+                                      int tolerance)
+{
+    const std::pair<int, int> vxs = {horizontal_pan_, horizontal_pan_ + rect.w};
+    return IsSpansOverlap(xs, vxs, tolerance);
+}
+std::vector<std::string> DBusStatListView::ColumnHeaders()
+{
+    return visible_columns_;
+}
+
+std::vector<int> DBusStatListView::ColumnWidths()
+{
+    std::vector<int> widths = {8}; // for "Msg/s"
+    std::vector<std::string> agg_headers = visible_columns_;
+    std::vector<int> agg_widths(agg_headers.size(), 0);
+    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
+    {
+        agg_widths[i] = column_widths_[agg_headers[i]];
+    }
+    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
+    return widths;
+}
+
+// Coordinate systems are in world space, +x faces to the right
+// Viewport:            [horizontal_pan_,   horizontal_pan_ + rect.w]
+// Contents:  [  column_width[0]  ][  column_width[1] ][  column_width[2]  ]
+void DBusStatListView::PanViewportOrMoveHighlightedColumn(const int delta_x)
+{
+    // If the column to the left is visible, highlight it
+    const int N = static_cast<int>(ColumnHeaders().size());
+    bool col_idx_changed = false;
+    if (delta_x < 0)
+    { // Pan left
+        if (highlight_col_idx_ > 0)
+        {
+            std::pair<int, int> xs_left =
+                GetXSpanForColumn(highlight_col_idx_ - 1);
+            if (IsXSpanVisible(xs_left, -1))
+            {
+                highlight_col_idx_--;
+                col_idx_changed = true;
+            }
+        }
+        if (!col_idx_changed)
+        {
+            horizontal_pan_ += delta_x;
+        }
+    }
+    else if (delta_x > 0)
+    { // Pan right
+        if (highlight_col_idx_ < N - 1)
+        {
+            std::pair<int, int> xs_right =
+                GetXSpanForColumn(highlight_col_idx_ + 1);
+            if (IsXSpanVisible(xs_right, -1))
+            {
+                highlight_col_idx_++;
+                col_idx_changed = true;
+            }
+        }
+        if (!col_idx_changed)
+        {
+            horizontal_pan_ += delta_x;
+        }
+    }
+}
+
+void DBusStatListView::OnKeyDown(const std::string& key)
+{
+    {
+        switch (curr_menu_state_)
+        {
+            case LeftSide:
+            {
+                if (key == "up")
+                {
+                    menu1_->OnKeyDown("up");
+                }
+                else if (key == "down")
+                {
+                    menu1_->OnKeyDown("down");
+                }
+                else if (key == "right")
+                {
+                    SetMenuState(RightSide);
+                }
+                else if (key == "enter")
+                {
+                    SetMenuState(Hidden);
+                }
+                else if (key == "space")
+                {
+                    std::string ch;
+                    if (menu1_->RemoveHighlightedItem(&ch))
+                    {
+                        menu2_->AddItem(ch);
+                    }
+                }
+                break;
+            }
+            case RightSide:
+            {
+                if (key == "up")
+                {
+                    menu2_->OnKeyDown("up");
+                }
+                else if (key == "down")
+                {
+                    menu2_->OnKeyDown("down");
+                }
+                else if (key == "left")
+                {
+                    SetMenuState(LeftSide);
+                }
+                else if (key == "enter")
+                {
+                    SetMenuState(Hidden);
+                }
+                else if (key == "space")
+                {
+                    std::string ch;
+                    if (menu2_->RemoveHighlightedItem(&ch))
+                    {
+                        menu1_->AddItem(ch);
+                    }
+                }
+                break;
+            }
+            case Hidden:
+            {
+                if (key == "enter")
+                {
+                    switch (last_menu_state_)
+                    {
+                        case LeftSide:
+                        case RightSide:
+                            SetMenuState(last_menu_state_);
+                            break;
+                        default:
+                            SetMenuState(LeftSide);
+                    }
+                }
+                else if (key == "left")
+                {
+                    PanViewportOrMoveHighlightedColumn(-2);
+                }
+                else if (key == "right")
+                {
+                    PanViewportOrMoveHighlightedColumn(2);
+                }
+                else if (key == "up")
+                {
+                    disp_row_idx_--;
+                    if (disp_row_idx_ < 0)
+                    {
+                        disp_row_idx_ = 0;
+                    }
+                }
+                else if (key == "down")
+                {
+                    disp_row_idx_++;
+                    const int N = static_cast<int>(stats_snapshot_.size());
+                    if (disp_row_idx_ >= N)
+                    {
+                        disp_row_idx_ = N - 1;
+                    }
+                }
+                else if (key == "a")
+                {
+                    sort_order_ = SortOrder::Ascending;
+                    sort_col_idx_ = highlight_col_idx_;
+                    break;
+                }
+                else if (key == "d")
+                {
+                    sort_order_ = SortOrder::Descending;
+                    sort_col_idx_ = highlight_col_idx_;
+                    break;
+                }
+                break;
+            }
+        }
+    }
+    Render();
+}
+
+// Window C
+void DBusStatListView::Render()
+{
+    werase(win);
+    if (!visible_)
+        return;
+    int num_lines_shown = rect.h - 3;
+    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
+    {
+        menu1_->Render();
+        menu2_->Render();
+        num_lines_shown -= (menu_h_ + 3);
+        // Draw the arrow
+        const int x1 = menu1_->rect_.x;
+        const int h1 = menu1_->rect_.h;
+        const int x2 = menu2_->rect_.x;
+        const int w2 = menu2_->rect_.w;
+        const int y1 = menu1_->rect_.y;
+        const int arrow_x = (x1 + x2 + w2) / 2 - 2;
+        const int arrow_y = y1 + 2;
+        const int caption_x = x1;
+        const int caption_y = y1 + h1;
+        for (int x = 1; x < rect.w - 1; x++)
+        {
+            mvwaddch(win, y1 - 3, x, '-');
+        }
+        mvwprintw(win, y1 - 3, arrow_x - 8, "Press [Enter] to show/hide");
+        mvwprintw(win, y1 - 2, caption_x - 5,
+                  "DBus fields for aggregating and sorting results:");
+        if (curr_menu_state_ == LeftSide)
+        {
+            mvwprintw(win, y1 - 1, x1 - 4, "--[ Available Fields ]--");
+            mvwprintw(win, y1 - 1, x2 - 4, "--- Active Fields ---");
+        }
+        else
+        {
+            mvwprintw(win, y1 - 1, x1 - 4, "--- Available Fields ---");
+            mvwprintw(win, y1 - 1, x2 - 4, "--[ Active Fields ]--");
+        }
+        if (curr_menu_state_ == LeftSide)
+        {
+            mvwprintw(win, arrow_y, arrow_x, "-->");
+            mvwprintw(win, caption_y, caption_x,
+                      "Press [Space] to move to the right");
+        }
+        else
+        {
+            mvwprintw(win, arrow_y, arrow_x, "<--");
+            mvwprintw(win, caption_y, caption_x,
+                      "Press [Space] to move to the left");
+        }
+    }
+    std::vector<std::string> headers;
+    std::vector<int> widths;
+    visible_columns_ = g_dbus_statistics->GetFieldNames();
+    std::vector<std::string> agg_headers = visible_columns_;
+    std::vector<int> agg_widths(agg_headers.size(), 0);
+    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
+    {
+        agg_widths[i] = column_widths_[agg_headers[i]];
+    }
+    headers.insert(headers.end(), agg_headers.begin(), agg_headers.end());
+    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
+    std::vector<int> xs;
+    int curr_x = 2 - horizontal_pan_;
+    for (const int w : widths)
+    {
+        xs.push_back(curr_x);
+        curr_x += w;
+    }
+    const int N = headers.size();
+    // Bound col_idx_
+    if (highlight_col_idx_ >= N)
+    {
+        highlight_col_idx_ = N - 1;
+    }
+    // Render column headers
+    for (int i = 0; i < N; i++)
+    {
+        std::string s = headers[i];
+        // 1 char outside boundary = start printing from the second character,
+        // etc
+
+        // Print "<" for Ascending order (meaning: row 0 < row 1 < row 2 ... )
+        // Print ">" for Descending order (meaning: row 0 > row 1 > row 2 ... )
+        if (sort_col_idx_ == i)
+        {
+            if (sort_order_ == SortOrder::Ascending)
+            {
+                s.push_back('<');
+            }
+            else
+            {
+                s.push_back('>');
+            }
+        }
+
+        // Highlight the "currently-selected column"
+        if (highlight_col_idx_ == i)
+        {
+            wattrset(win, 0);
+            wattron(win, A_REVERSE);
+        }
+        else
+        {
+            wattrset(win, 0);
+            wattron(win, A_UNDERLINE);
+        }
+        int x = xs[i];
+        if (x < 0)
+        {
+            if (-x < static_cast<int>(s.size()))
+            {
+                s = s.substr(-x);
+            }
+            else
+                s = "";
+            x = 0;
+        }
+        mvwaddstr(win, 1, x, s.c_str());
+    }
+    wattrset(win, 0);
+    // Time since the last update of Window C
+    float interval_secs = g_dbus_statistics->seconds_since_last_sample_;
+    if (interval_secs == 0)
+    {
+        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
+    }
+
+    stats_snapshot_ = g_dbus_statistics->StatsSnapshot();
+    const int nrows = static_cast<int>(stats_snapshot_.size());
+    const std::vector<DBusTopSortField> fields = g_dbus_statistics->GetFields();
+    const int ncols = static_cast<int>(fields.size());
+    // Merge the list of DBus Message properties & computed metrics together
+    std::map<std::vector<std::string>, DBusTopComputedMetrics>::iterator itr =
+        stats_snapshot_.begin();
+    struct StringOrFloat
+    { // Cannot use union so using struct
+        std::string s;
+        float f;
+    };
+
+    // "Stage" the snapshot for displaying in the form of a spreadsheet
+    std::vector<std::pair<StringOrFloat, std::vector<std::string>>>
+        stats_snapshot_staged;
+    const DBusTopSortField sort_field = fields[sort_col_idx_];
+    const bool is_sort_key_numeric = DBusTopSortFieldIsNumeric(sort_field);
+
+    for (int i = 0; i < nrows; i++) // One row of cells
+    {
+        int idx0 = 0; // indexing into the std::vector<string> of each row
+        std::vector<std::string> row;
+
+        StringOrFloat sort_key; // The key used for sorting
+        for (int j = 0; j < ncols; j++) // one column in the row
+        {
+            DBusTopSortField field = fields[j];
+            // Populate the content of stats_snapshot_staged
+
+            StringOrFloat sof; // Represents this column
+            
+            // When we haven't used up all
+            if (idx0 < static_cast<int>(itr->first.size()))
+            {
+                sof.s = itr->first[idx0];
+            }
+            switch (field)
+            {
+                case kSender:      // string
+                case kDestination: // string
+                case kInterface:   // string
+                case kPath:        // string
+                case kMember:      // string
+                case kSenderPID:   // numeric
+                case kSenderCMD:   // string
+                    row.push_back(itr->first[idx0]);
+                    idx0++;
+                    if (field == kSenderPID)
+                    {
+                        // Note: attempting to std::atof("(unknown)") on the BMC
+                        // will cause hang. And GDB won't show backtrace.
+                        if (sof.s == "(unknown)")
+                        {
+                            if (sort_order_ == Ascending)
+                            {
+                                sof.f = -1;
+                            }
+                            else
+                            {
+                                sof.f = 1e20;
+                            }
+                        }
+                        else
+                        {
+                            sof.f = std::atof(sof.s.c_str());
+                        }
+                    }
+                    break;
+                case kMsgPerSec: // Compute "messages per second"
+                {
+                    int numbers[] = {
+                        itr->second.num_method_calls,
+                        itr->second.num_method_returns,
+                        itr->second.num_signals,
+                        itr->second.num_errors,
+                    };
+                    int the_sum = 0; // For sorting
+
+                    std::string s; // String representation in the form or
+                                   // "1.00/2.00/3.00/4.00"
+                    for (int i = 0; i < 4; i++)
+                    {
+                        the_sum += numbers[i];
+                        if (i > 0)
+                            s += "/";
+                        float per_sec = numbers[i] / interval_secs;
+                        s += FloatToString(per_sec);
+                    }
+
+                    row.push_back(s);
+                    sof.f = the_sum;
+                    break;
+                }
+                case kAverageLatency: // Compute "average Method Call latency"
+                    const DBusTopComputedMetrics& m = itr->second;
+                    if (m.num_method_calls == 0)
+                    {
+                        row.push_back("n/a");
+                        if (sort_order_ == Ascending)
+                        {
+                            sof.f = -1; // Put to the top
+                        }
+                        else
+                        {
+                            sof.f = 1e20; // Put to the top
+                        }
+                    }
+                    else
+                    {
+                        float avg_latency_usec =
+                            m.total_latency_usec / m.num_method_calls;
+                        row.push_back(FloatToString(avg_latency_usec));
+                        sof.f = avg_latency_usec;
+                    }
+                    break;
+            }
+            if (j == sort_col_idx_)
+            {
+                sort_key = sof;
+            }
+        }
+        stats_snapshot_staged.push_back(std::make_pair(sort_key, row));
+        itr++;
+    }
+    
+    // Sort the "staged snapshot" using the sort_key, using different functions
+    // depending on whether sort key is numeric or string
+    if (is_sort_key_numeric)
+    {
+        std::sort(
+            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
+            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
+               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
+                return a.first.f < b.first.f;
+            });
+    }
+    else
+    {
+        std::sort(
+            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
+            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
+               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
+                return a.first.s < b.first.s;
+            });
+    }
+    
+    if (sort_order_ == Descending)
+    {
+        std::reverse(stats_snapshot_staged.begin(),
+                     stats_snapshot_staged.end());
+    }
+    // Minus 2 because of "msgs/s" and "+"
+    const int num_fields = N;
+    // The Y span of the area for rendering the "spreadsheet"
+    const int y0 = 2, y1 = y0 + num_lines_shown - 1;
+    // Key is sender, destination, interface, path, etc
+    for (int i = 0, shown = 0;
+        i + disp_row_idx_ < static_cast<int>(stats_snapshot_staged.size()) &&
+        shown < num_lines_shown;
+        i++, shown++)
+    {
+        std::string s;
+        int x = 0;
+        const std::vector<std::string> key =
+            stats_snapshot_staged[i + disp_row_idx_].second;
+        for (int j = 0; j < num_fields; j++)
+        {
+            x = xs[j];
+            s = key[j];
+            // Determine column width limit for this particular column
+            int col_width = 100;
+            if (j < num_fields - 1)
+            {
+                col_width = xs[j + 1] - xs[j] - 1;
+            }
+            s = Ellipsize(s, col_width);
+            if (x < 0)
+            {
+                if (-x < static_cast<int>(s.size()))
+                    s = s.substr(-x);
+                else
+                    s = "";
+                x = 0;
+            }
+            // Trim if string overflows to the right
+            if (x + static_cast<int>(s.size()) > rect.w)
+            {
+                s = s.substr(0, rect.w - x);
+            }
+            mvwaddstr(win, 2 + i, x, s.c_str());
+        }
+    }
+    // Overflows past the top ...
+    if (disp_row_idx_ > 0)
+    {
+        std::string x = " [+" + std::to_string(disp_row_idx_) + " rows above]";
+        mvwaddstr(win, y0, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
+    }
+    // Overflows past the bottom ...
+    const int last_disp_row_idx = disp_row_idx_ + num_lines_shown - 1;
+    if (last_disp_row_idx < nrows - 1)
+    {
+        std::string x = " [+" +
+                        std::to_string((nrows - 1) - last_disp_row_idx) +
+                        " rows below]";
+        mvwaddstr(win, y1, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
+    }
+    DrawBorderIfNeeded();
+    wrefresh(win);
+}
+
+void DBusStatListView::OnResize(int win_w, int win_h)
+{
+    rect.y = 8 - MARGIN_BOTTOM;
+    rect.w = win_w - (win_w / 2) + 1; // Perfectly overlap on the vertical edge
+    rect.x = win_w - rect.w;
+    rect.h = win_h - rect.y - MARGIN_BOTTOM;
+    const int x0 = rect.w / 2 - menu_w_ - menu_margin_ / 2;
+    const int x1 = x0 + menu_margin_ + menu_w_;
+    const int menu_y = rect.h - menu_h_;
+    menu1_->SetRect(Rect(x0, menu_y, menu_w_, menu_h_)); // Local coordinates
+    menu1_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
+    menu2_->SetRect(Rect(x1, menu_y, menu_w_, menu_h_));
+    menu2_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
+    UpdateWindowSizeAndPosition();
+}
+
+std::vector<DBusTopSortField> DBusStatListView::GetSortFields()
+{
+    std::vector<DBusTopSortField> ret;
+    const int N = sizeof(FieldNames) / sizeof(FieldNames[0]);
+    for (const std::string& s : menu2_->Items())
+    {
+        for (int i = 0; i < N; i++)
+        {
+            if (FieldNames[i] == s)
+            {
+                ret.push_back(static_cast<DBusTopSortField>(i));
+                break;
+            }
+        }
+    }
+    return ret;
+}
+
+std::string DBusStatListView::GetStatusString()
+{
+    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
+    {
+        return "[Enter]=Hide Panel [Space]=Choose Entry [Arrow Keys]=Move "
+               "Cursor";
+    }
+    else
+    {
+        return "[Enter]=Show Column Select Panel [Arrow Keys]=Pan View";
+    }
+}
+
+void FooterView::Render()
+{
+    werase(win);
+    const time_t now = time(nullptr);
+    const char* date_time = ctime(&now);
+    wattrset(win, 0);
+    std::string help_info;
+    if (g_current_active_view == nullptr)
+    {
+        help_info = "Press [Tab] to cycle through views";
+    }
+    else
+    {
+        help_info = g_current_active_view->GetStatusString();
+    }
+    mvwaddstr(win, 0, 1, date_time);
+    mvwaddstr(win, 0, rect.w - int(help_info.size()) - 1, help_info.c_str());
+    wrefresh(win);
+}
diff --git a/dbus-top/views.hpp b/dbus-top/views.hpp
new file mode 100644
index 0000000..d4f3779
--- /dev/null
+++ b/dbus-top/views.hpp
@@ -0,0 +1,539 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include "analyzer.hpp"
+#include "bargraph.hpp"
+#include "main.hpp"
+#include "menu.hpp"
+#include "sensorhelper.hpp"
+
+#include <ncurses.h>
+#include <string>
+#include <vector>
+constexpr int MARGIN_BOTTOM = 1;
+class DBusTopWindow
+{
+  public:
+    DBusTopWindow()
+    {
+        win = newwin(25, 80, 0, 0); // Default to 80x25, will be updated
+        has_border_ = true;
+        focused_ = false;
+        selectable_ = true;
+        visible_ = true;
+        maximize_ = false;
+    }
+
+    virtual ~DBusTopWindow()
+    {}
+    virtual void OnKeyDown(const std::string& key) = 0;
+    virtual void Render() = 0;
+    virtual void OnResize(int win_w, int win_h) = 0;
+    void UpdateWindowSizeAndPosition()
+    {
+        mvwin(win, rect.y, rect.x);
+        wresize(win, rect.h, rect.w);
+    }
+
+    void DrawBorderIfNeeded()
+    {
+        if (focused_)
+        {
+            wborder(win, '*', '*', '*', '*', '*', '*', '*', '*');
+        }
+        else
+        {
+            wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
+        }
+        wrefresh(win);
+    }
+
+    virtual void RecreateWindow()
+    {
+        delwin(win);
+        win = newwin(25, 80, 0, 0);
+        UpdateWindowSizeAndPosition();
+    }
+
+    virtual std::string GetStatusString() = 0;
+    WINDOW* win;
+    Rect rect;
+    bool has_border_;
+    bool focused_;
+    bool selectable_;
+    bool maximize_;
+    bool visible_;
+};
+
+class SummaryView : public DBusTopWindow
+{
+  public:
+    SummaryView() : DBusTopWindow()
+    {}
+    void Render() override;
+    void OnResize(int win_w, int win_h) override
+    {
+        rect.h = 8;
+        rect.w = win_w;
+        rect.x = 0;
+        rect.y = 0;
+        UpdateWindowSizeAndPosition();
+    }
+
+    void UpdateDBusTopStatistics(DBusTopStatistics* stat);
+    void OnKeyDown(const std::string& key) override
+    {}
+    std::string GetStatusString() override
+    {
+        return "Summary View";
+    }
+
+  private:
+    float method_call_, method_return_, signal_, error_, total_;
+};
+
+class SensorDetailView : public DBusTopWindow
+{
+  public:
+    SensorDetailView() : DBusTopWindow()
+    {
+        choice_ = -999; // -999 means invalid
+        h_padding = 2;
+        h_spacing = 3;
+        col_width = 15;
+        idx0 = idx1 = -999;
+        state = SensorList;
+    }
+
+    void Render() override;
+    int DispSensorsPerColumn()
+    {
+        return rect.h - 3;
+    }
+
+    int DispSensorsPerRow()
+    {
+        int ncols = 0;
+        while (true)
+        {
+            int next = ncols + 1;
+            int w = 2 * h_padding + col_width * next;
+            if (next > 1)
+                w += (next - 1) * h_spacing;
+            if (w <= rect.w - 2)
+            {
+                ncols = next;
+            }
+            else
+            {
+                break;
+            }
+        }
+        return ncols;
+    }
+
+    void OnKeyDown(const std::string& key) override
+    {
+        if (state == SensorList)
+        { // Currently in sensor list
+            if (key == "right")
+            {
+                MoveChoiceCursorHorizontally(1);
+            }
+            else if (key == "left")
+            {
+                MoveChoiceCursorHorizontally(-1);
+            }
+            else if (key == "up")
+            {
+                MoveChoiceCursor(-1, true);
+            }
+            else if (key == "down")
+            {
+                MoveChoiceCursor(1, true);
+            }
+            else if (key == "enter")
+            {
+                if (choice_ != -999)
+                {
+                    state = SensorDetail;
+                }
+            }
+            else if (key == "escape")
+            {
+                choice_ = -999;
+            }
+        }
+        else if (state == SensorDetail)
+        { // Currently focusing on a sensor
+            if (key == "right" || key == "down")
+            {
+                MoveChoiceCursor(1, true);
+            }
+            else if (key == "left" || key == "up")
+            {
+                MoveChoiceCursor(-1, true);
+            }
+            else if (key == "escape")
+            {
+                state = SensorList;
+            }
+        }
+
+        Render(); // This window is already on top, redrawing won't corrupt
+    }
+
+    void MoveChoiceCursor(int delta, bool wrap_around = true)
+    {
+        const int ns = sensor_ids_.size();
+        if (ns < 1)
+            return;
+        // First of all, if cursor is inactive, activate it
+        if (choice_ == -999)
+        {
+            if (delta > 0)
+            {
+                choice_ = 0;
+                curr_sensor_id_ = sensor_ids_[0];
+                return;
+            }
+            else
+            {
+                choice_ = ns - 1;
+                curr_sensor_id_ = sensor_ids_.back();
+                return;
+            }
+        }
+        int choice_next = choice_ + delta;
+        while (choice_next >= ns)
+        {
+            if (wrap_around)
+            {
+                choice_next -= ns;
+            }
+            else
+            {
+                choice_next = ns - 1;
+            }
+        }
+        while (choice_next < 0)
+        {
+            if (wrap_around)
+            {
+                choice_next += ns;
+            }
+            else
+            {
+                choice_next = 0;
+            }
+        }
+        choice_ = choice_next;
+        curr_sensor_id_ = sensor_ids_[choice_];
+    }
+
+    void MoveChoiceCursorHorizontally(int delta)
+    {
+        if (delta != 0 && delta != -1 && delta != 1)
+            return;
+        const int ns = sensor_ids_.size();
+        if (ns < 1)
+            return;
+        if (choice_ == -999)
+        {
+            if (delta > 0)
+            {
+                choice_ = 0;
+                curr_sensor_id_ = sensor_ids_[0];
+                return;
+            }
+            else
+            {
+                curr_sensor_id_ = sensor_ids_.back();
+                choice_ = ns - 1;
+                return;
+            }
+        }
+        const int nrows = DispSensorsPerColumn();
+        int tot_columns = (ns - 1) / nrows + 1;
+        int num_rows_last_column = ns - nrows * (tot_columns - 1);
+        int y = choice_ % nrows, x = choice_ / nrows;
+        if (delta == 1)
+        {
+            x++;
+        }
+        else
+        {
+            x--;
+        }
+        bool overflow_to_right = false;
+        if (y < num_rows_last_column)
+        {
+            if (x >= tot_columns)
+            {
+                overflow_to_right = true;
+            }
+        }
+        else
+        {
+            if (x >= tot_columns - 1)
+            {
+                overflow_to_right = true;
+            }
+        }
+        bool overflow_to_left = false;
+        if (x < 0)
+        {
+            overflow_to_left = true;
+        }
+        {
+            if (overflow_to_right)
+            {
+                y++;
+                // overflow past the right of window
+                // Start probing next line
+                if (y >= nrows)
+                {
+                    choice_ = 0;
+                    return;
+                }
+                else
+                {
+                    choice_ = y;
+                    return;
+                }
+            }
+            else if (overflow_to_left)
+            { // overflow past the left of window
+                y--;
+                if (y < 0)
+                { // overflow past the top of window
+                    // Focus on the visually bottom-right entry
+                    if (num_rows_last_column == nrows)
+                    { // last col fully populated
+                        choice_ = ns - 1;
+                    }
+                    else
+                    { // last column is not fully populated
+                        choice_ = ns - num_rows_last_column - 1;
+                    }
+                    return;
+                }
+                else
+                {
+                    if (y < num_rows_last_column)
+                    {
+                        choice_ = nrows * (tot_columns - 1) + y;
+                    }
+                    else
+                    {
+                        choice_ = nrows * (tot_columns - 2) + y;
+                    }
+                }
+            }
+            else
+            {
+                choice_ = y + x * nrows;
+            }
+        }
+        curr_sensor_id_ = sensor_ids_[choice_];
+    }
+
+    // Cache the sensor list in the sensor snapshot
+    void UpdateSensorSnapshot(SensorSnapshot* snapshot)
+    {
+        std::string old_sensor_id = "";
+        if (choice_ != -999)
+        {
+            old_sensor_id = sensor_ids_[choice_];
+        }
+        std::vector<std::string> new_sensors =
+            snapshot->GetDistinctSensorNames();
+        if (new_sensors == sensor_ids_)
+        {
+            return; // Nothing is changed
+        }
+        // Assume changed
+        sensor_ids_ = new_sensors;
+        choice_ = -999;
+        for (int i = 0; i < static_cast<int>(new_sensors.size()); i++)
+        {
+            if (new_sensors[i] == old_sensor_id)
+            {
+                choice_ = i;
+                break;
+                curr_sensor_id_ = sensor_ids_[choice_];
+            }
+        }
+    }
+
+    void OnResize(int win_w, int win_h) override
+    {
+        rect.x = 0;
+        rect.y = 8 - MARGIN_BOTTOM;
+        rect.w = win_w / 2;
+        rect.h = win_h - rect.y - MARGIN_BOTTOM;
+        UpdateWindowSizeAndPosition();
+    }
+
+    std::vector<std::string> sensor_ids_;
+    // We need to keep track of the currently-selected sensor ID because
+    // the sensor ID might theoretically become invalidated at any moment, and
+    // we should allow the UI to show an error gracefully in that case.
+    std::string curr_sensor_id_;
+    int choice_;
+    int h_padding;
+    int h_spacing;
+    int col_width;
+    int idx0, idx1; // Range of sensors on display
+    enum State
+    {
+        SensorList,
+        SensorDetail,
+    };
+
+    State state;
+    std::string GetStatusString() override;
+};
+
+class DBusStatListView : public DBusTopWindow
+{
+  public:
+    DBusStatListView();
+    void Render() override;
+    void OnResize(int win_w, int win_h) override;
+    void OnKeyDown(const std::string& key) override;
+    int horizontal_pan_;
+    int menu_h_, menu_w_, menu_margin_;
+    ArrowKeyNavigationMenu* menu1_;
+    ArrowKeyNavigationMenu* menu2_;
+    int highlight_col_idx_; // Currently highlighted column
+    int row_idx_;           // Currently highlighted row
+
+    int sort_col_idx_; // Column used for sorting
+    enum SortOrder
+    {
+        Ascending,
+        Descending,
+    };
+    SortOrder sort_order_;
+
+    int disp_row_idx_; // From which row to start displaying? (essentially a
+                       // vertical scroll bar)
+    int last_choices_[2]; // Last choice index on either side
+    enum MenuState
+    {
+        Hidden,
+        LeftSide,  // When the user is choosing an entry on the left side
+        RightSide, // When the user is choosing an entry on the right side
+    };
+
+    std::vector<DBusTopSortField> GetSortFields();
+    MenuState curr_menu_state_, last_menu_state_;
+    std::string GetStatusString() override;
+    void RecreateWindow()
+    {
+        delwin(win);
+        win = newwin(25, 80, 0, 0);
+        menu1_->win_ = win;
+        menu2_->win_ = win;
+        UpdateWindowSizeAndPosition();
+    }
+    
+  private:
+    void SetMenuState(MenuState s)
+    {
+        last_menu_state_ = curr_menu_state_;
+        // Moving out from a certain side: save the last choice of that side
+        switch (curr_menu_state_)
+        {
+            case LeftSide:
+                if (s == RightSide)
+                {
+                    last_choices_[0] = menu1_->Choice();
+                    menu1_->Deselect();
+                }
+                break;
+            case RightSide:
+                if (s == LeftSide)
+                {
+                    last_choices_[1] = menu2_->Choice();
+                    menu2_->Deselect();
+                }
+                break;
+            default:
+                break;
+        }
+        // Moving into a certain side: save the cursor
+        switch (s)
+        {
+            case LeftSide:
+                if (!menu1_->Empty())
+                {
+                    menu1_->SetChoiceAndConstrain(last_choices_[0]);
+                }
+                break;
+            case RightSide:
+                if (!menu2_->Empty())
+                {
+                    menu2_->SetChoiceAndConstrain(last_choices_[1]);
+                }
+                break;
+            default:
+                break;
+        }
+        curr_menu_state_ = s;
+    }
+    void PanViewportOrMoveHighlightedColumn(const int delta_x);
+    // ColumnHeaders and ColumnWidths are the actual column widths used for
+    // display. They are "msg/s" or "I2c/s" prepended to the chosen set of
+    // fields.
+    std::vector<std::string> ColumnHeaders();
+    std::vector<int> ColumnWidths();
+    // X span, for checking visibility
+    std::pair<int, int> GetXSpanForColumn(const int col_idx);
+    bool IsXSpanVisible(const std::pair<int, int>& xs,
+                        const int tolerance); // uses horizontal_pan_
+    std::vector<std::string> visible_columns_;
+    std::unordered_map<std::string, int> column_widths_;
+    std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_snapshot_;
+};
+
+class FooterView : public DBusTopWindow
+{
+  public:
+    FooterView() : DBusTopWindow()
+    {
+        selectable_ = false; // Cannot be selected by the tab key
+    }
+
+    void OnKeyDown(const std::string& key) override
+    {}
+    void OnResize(int win_w, int win_h) override
+    {
+        rect.h = 1;
+        rect.w = win_w;
+        rect.x = 0;
+        rect.y = win_h - 1;
+        UpdateWindowSizeAndPosition();
+    }
+
+    void Render() override;
+    std::string GetStatusString() override
+    {
+        return "";
+    }
+
+};
diff --git a/dbus-top/xmlparse.cpp b/dbus-top/xmlparse.cpp
new file mode 100644
index 0000000..2e4b1a3
--- /dev/null
+++ b/dbus-top/xmlparse.cpp
@@ -0,0 +1,193 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "xmlparse.hpp"
+#include "main.hpp"
+
+int Munch(const std::string& sv, int* idx, std::string* out)
+{
+    if (*idx >= static_cast<int>(sv.size()))
+        return -INVALID;
+    while (::isspace(sv[*idx]))
+    {
+        (*idx)++;
+    }
+    int ret = 0;
+    *out = "";
+    int quote_state = 0; // 0: not seen, 1: seen opening quotation, 2: ended
+    while (*idx < static_cast<int>(sv.size()))
+    {
+        const char ch = sv[*idx];
+        if (::isspace(ch) && quote_state != 1)
+        {
+            break;
+        }
+        (*idx)++;
+        if (ch == '<')
+        {
+            if (*idx < static_cast<int>(sv.size()) && sv[*idx] == '!')
+            {
+                ret = 10; // Comment
+            }
+            else if (*idx < static_cast<int>(sv.size()) && sv[*idx] == '/')
+            {
+                ret = 22; // Closing tag
+                (*idx)++; // Skip the '/'
+            }
+            else
+            {
+                ret = 1; // <
+            }
+        }
+        else if (ch == '>')
+        {
+            if (ret == 1)
+            {
+                ret = 12;
+            } // < >
+            else if (ret == 22)
+            {}
+            else
+                ret = 2; //   >
+            if (out->size() == 0)
+            {
+                (*idx)++;
+            }
+            break; // Do not consume
+        }
+        else if (ch == '\"')
+        {
+            ret = 3; //
+            switch (quote_state)
+            {
+                case 0:
+                {
+                    quote_state = 1;
+                    continue;
+                }
+                case 1:
+                {
+                    quote_state = 2;
+                    break;
+                }
+            }
+        }
+        else if (ch == '/' && *idx < static_cast<int>(sv.size()) &&
+                 sv[*idx] == '>')
+        {
+            ret = 22; // Closing tag
+            (*idx)++;
+            break;
+        }
+        else
+        {
+            out->push_back(ch);
+        }
+    }
+    return ret;
+}
+
+XMLNode* ParseXML(const std::string& sv)
+{
+    int verbose = 0;
+    char* v = getenv("VERBOSE");
+    if (v)
+    {
+        verbose = std::atoi(v);
+    }
+    int idx = 0;
+    std::string out;
+    int res;
+    std::vector<std::string> tags;
+    std::vector<XMLNode*> nodestack;
+    XMLNode* root = nullptr;
+    if (verbose > 0)
+    {
+        printf("%s\n", sv.c_str());
+    }
+    while ((res = Munch(sv, &idx, &out)) != -INVALID)
+    {
+        if (res == 1 || res == 12)
+        {
+            XMLNode* newnode = new XMLNode(out);
+            if (tags.empty())
+            {
+                root = newnode;
+            }
+            else
+            {
+                nodestack.back()->AddChild(newnode);
+            }
+            tags.push_back(out);
+            nodestack.push_back(newnode);
+        }
+
+        // Add name (has to be before pop_back)
+        if (out.find("name=") == 0)
+        {
+            nodestack.back()->SetName(out.substr(5));
+        }
+
+        if (res == 22 && tags.size() > 0)
+        {
+            tags.pop_back();
+            nodestack.pop_back();
+        }
+        if (verbose >= 2)
+        {
+            printf("Munch %d %s, tags:", res, out.c_str());
+            for (const std::string& x : tags)
+            {
+                printf(" %s", x.c_str());
+            }
+            printf("\n");
+        }
+    }
+    return root;
+}
+
+void DeleteTree(XMLNode* x)
+{
+    for (XMLNode* ch : x->children)
+    {
+        DeleteTree(ch);
+    }
+    delete x;
+}
+
+std::vector<std::string> XMLNode::GetChildNodeNames()
+{
+    std::vector<std::string> ret;
+    for (XMLNode* n : children)
+    {
+        if (n->tag == "node")
+        {
+            ret.push_back(n->fields["name"]);
+        }
+    }
+    return ret;
+}
+
+std::vector<std::string> XMLNode::GetInterfaceNames()
+{
+    std::vector<std::string> ret;
+    for (XMLNode* n : children)
+    {
+        if (n->tag == "interface")
+        {
+            ret.push_back(n->fields["name"]);
+        }
+    }
+    return ret;
+}
\ No newline at end of file
diff --git a/dbus-top/xmlparse.hpp b/dbus-top/xmlparse.hpp
new file mode 100644
index 0000000..3a76e9a
--- /dev/null
+++ b/dbus-top/xmlparse.hpp
@@ -0,0 +1,67 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+
+class XMLNode
+{
+  public:
+    std::string tag;
+    std::map<std::string, std::string> fields;
+    std::vector<XMLNode*> children;
+    std::vector<XMLNode*> interfaces;
+    XMLNode(const std::string& t) : tag(t)
+    {}
+
+    void AddChild(XMLNode* x)
+    {
+        children.push_back(x);
+    }
+
+    void do_Print(int indent)
+    {
+        for (int i = 0; i < indent; i++)
+            printf("  ");
+        printf("%s", tag.c_str());
+        if (fields["name"] != "")
+        {
+            printf(" name=[%s]", fields["name"].c_str());
+        }
+        printf("\n");
+        for (XMLNode* ch : children)
+        {
+            ch->do_Print(indent + 1);
+        }
+    }
+
+    void Print()
+    {
+        do_Print(0);
+    }
+
+    void SetName(const std::string& n)
+    {
+        fields["name"] = n;
+    }
+    
+    std::vector<std::string> GetChildNodeNames();
+    std::vector<std::string> GetInterfaceNames();
+};
+
+XMLNode* ParseXML(const std::string& sv);
+void DeleteTree(XMLNode* x);
