diff --git a/dbus-top/.clang-format b/dbus-top/.clang-format
deleted file mode 100644
index 3652c56..0000000
--- a/dbus-top/.clang-format
+++ /dev/null
@@ -1,113 +0,0 @@
----
-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
deleted file mode 100644
index a2ae220..0000000
--- a/dbus-top/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-oe-logs
-oe-workdir
-.vscode
diff --git a/dbus-top/README.md b/dbus-top/README.md
deleted file mode 100644
index b7be655..0000000
--- a/dbus-top/README.md
+++ /dev/null
@@ -1,214 +0,0 @@
-# Design Doc for dbus-top
-
-Author: Adedeji Adebisi (ziniblessed@google.com)
-
-Primary Assignee: Adedeji Adebisi
-
-Other contributors: Sui Chen (suichen@google.com) Alex Qiu (xqiu@google.com)
-
-Created: May 17, 2021
-
-## Problem Description
-
-Design and Implementation of a top-like tool for DBus. This tool shows metrics
-related to dbus connections such as message throughput, as well as system
-information available through DBus such as the list of sensors, in an attempt to
-understand some performance related issues on the BMC. The sensor information is
-extracted from well-known DBus services such as the Object Mapper, Inventory
-Manager, and Entity Manager. DBus-top shows the information conveniently that
-might otherwise require the user to type long commands or scripts.
-
-## Background and References
-
-This tool adds to the set of command-line based tools that run directly on the
-BMC. Using a tool that directly runs on the BMC, a user can debug problems
-in-situ, without needing to extract data from the BMC to the host for offline
-analysis. This tool resembles a typical top-like user interface, giving the user
-a top-down view of various DBus states. This tool is designed in the same logic
-as similarly-purposed, existing tools, each focusing on one particular field
-such as ctop (for containers), htop (for viewing process stats), iotop (for I/O
-throughput), iftop (for network traffic).
-
-## Requirements
-
-Constraints:
-
-1. BMC consoles may not be capable of displaying all text styles supported in
-   ncurses Dependency on libncurses which might add ~130KB overhead to the BMC’s
-   Flash space.
-2. Monitoring DBus should not incur so much performance overhead as to distort
-   measured values.
-3. Users are OpenBMC users and developers: This tool should help beginners learn
-   the basics of OpenBMC, as well as help seasoned developers quickly locate a
-   problem.
-
-Scope:
-
-1. This tool is standalone, self-sufficient, with minimum dependency on existing
-   software packages (only depends on basic packages like systemd, libdbus,
-   sdbus, sdbusplus, and libncurses.) Data size, transaction rates, bandwidth:
-   We will be looking at typically hundreds of DBus messages per second and
-   around 1 MB/s data throughput. The BMC’s processing power and memory capacity
-   are sufficient for the scale of the data this tool is processing.
-2. This tool should work on a live DBus as well as on a capture file (a pcap
-   file).
-3. This tool should work both on the host or the BMC. The UI design is scaled to
-   work with large numbers of sensors and different console sizes.
-
-## Proposed Design
-
-The proposed design is to layout a multi-window UI similar to how a tiled window
-manager does:
-
-```text
-+----------------------------------------------------------------------------+
-|Message Type          | msg/s        History                 (Total msg/s)  |
-|Method Call             45.00        -  .       .       .       .    -2300  |
-|Method Return           45.00        -  :       :       :       :    -1750  |
-|Signal                  53.00        -  :       :       :       :    -1200  |
-|Error                    0.00        -  :       :       :       :    -650   |
-|Total                  142.99        -:::.....:::.....:::.....:::....-100   |
-+-------------------------------------+--------------------------------------+
-| Columns 1-2 of 6      84 sensors    |   Msg/s   Sender  Destination        |
-|   vddq_efgh_out     vddcr_cpu1_in   |   7.50    :1.14   :1.48              |
-|   vddcr_cpu0_out    vddcr_soc1_out  |   7.50    :1.14   org.freedesktop.DB>|
-|   vddq_mnop_out     vddq_efgh_in    |   7.50    :1.48   :1.52              |
-|   vddcr_soc0_out    vddq_abcd_in    |   7.50    :1.48   org.freedesktop.DB>|
-|   vddq_ijkl_in      vddq_efgh_out   |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddcr_soc0_in     hotswap_pout    |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddcr_cpu0_in     vddcr_cpu1_in   |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddq_ijkl_out     vddq_efgh_in    |   5.00    :1.48   xyz.openbmc_projec>|
-|   vddcr_soc1_in     vddq_ijkl_out   |   5.00    :1.48   xyz.openbmc_projec>|
-|   hotswap_iout      vddcr_soc0_out  |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddq_abcd_in      vddcr_soc1_in   |   7.50    :1.48   xyz.openbmc_projec>|
-|   vddq_mnop_in      vddq_mnop_in    |   7.50    :1.52   xyz.openbmc_projec>|
-|   vddcr_cpu1_out    vddcr_cpu1_out  |   1.00    :1.70   (null)             |
-|   vddq_abcd_out     vddcr_cpu0_out  |   1.00    :1.70   :1.48              |
-+-------------------------------------+--------------------------------------+
- Fri Jul  2 15:50:08 2021                                    PRESS ? FOR HELP
-```
-
-The UI has 3 windows:
-
-### Top, summary window
-
-This window is divided into two sections:
-
-- The dbus traffic dump that shows the method calls, method returns,signals and
-  errors in every dbus callback. This is significant because it shows the
-  latency between every call back and the other section that shows the graph can
-  benefit from this.
-- The other part shows a history graph of these corresponding data and it is
-  designed this way to show users a pictorial representation of the callback
-  metrics.
-
-### Bottom-left, sensor detail window
-
-This window has two states:
-
-- The window shows the list of all sensors (as defined by DBus objects
-  implementing the xyz.openbmc_project.Sensor.Value) by default
-- When a sensor is selected, it shows the corresponding details including sensor
-  name, the dbus connection, PID and the dbus service associated with the
-  sensor. This will be helpful in understanding what is connected to the sensor
-  in a case of performance related to the sensor.
-
-The following is how the window might look once a sensor has been selected:
-
-```text
-+-------------------------------------------------+
-| Details for sensor cputemp0        Sensor 1/192 |
-| [DBus Info]                                     |
-| DBus Connection :  :1.234                       |
-| DBus Service    :  xyz.openbmc_project...       |
-| DBus Object Path:  /path/to/object              |
-|                                                 |
-| [Inventory Info]                                |
-| Association:                                    |
-|  - chassis: all_sensors                         |
-|                                                 |
-| [Visibility]                                    |
-|  - IPMI SEL: Yes                                |
-|  - Object Mapper: Yes                           |
-|  - Sensor Daemon: Yes                           |
-+-------------------------------------------------+
-```
-
-### Bottom-right, DBus stats list view window
-
-This window shows the stats of DBus connections in a list, aggregated by the
-fields of the user’s choice. These fields include sender, destination, path,
-interface, and message type.
-
-A menu is available that allows the user to select what fields to use to
-aggregate the entries in the window.
-
-```text
-+----------------------------------------+
-|Available Fields          Active Fields |
-|                                        |
-|Interface                 Sender        |
-|Path                 ---> Destination   |
-|Message Type         <---               |
-|Sender Process Name                     |
-+----------------------------------------+
-```
-
-The windows can be resized, or shown/hidden individually.
-
-Overview of the Program Structure:
-
-```text
-      UI Thread               Analysis Thread          Capture Thread
-     _______^_______        _________^__________      _________^______
-    /               \      /                    \    /                \
-
-          +-+-------+     +----------+   +-------+      +-----------+
-+-----+   | |User   |     | Call     | ,-|Message|<-.   |Become     |
-|User |   | |Setting|-. S | ObjMapper| | |Handler|  |M  |DBus       |
-|Input|   | `-------+ | o | Inv.Mgr  | | +-------+  |eD |Monitor    |
-+-----+   |         | |Kr | EntityMgr| |     |      |sB +-----------+
-   |      |Frontend | |et +----------+ |     V      |su       |
-   `----->|   UI    | |y    |          | +-------+  |as       V
-   Key    |         | |s    `----------->|Method |  |g  +------------+
-   Stroke |         | `-->+---------+  | |Call   |  |e  |DBus Capture|
-          |         |<-.  |Aggregate|  | |Tracker|  |s  +------------+
-          +---------+  |  |         |<-' +-------+  |      |
-           |     |     |  +---------+        |      +------'
-           V     V     |       |             |      |
-   +--------+ +-----+  |       V             V      |
-   |ncurses-| |Text-|  |   +-------+     +-------+  |   +-----------+
-   |based   | |based|  +---|Sensor |     |Sensor |  `---|PCAP Replay|
-   |UI      | |UI   |  |   |Stats  |     |Details|      +-----------+
-   +--------+ +-----+  |   +-------+     +-------+
-                       |                     |
-                       `---------------------'
-```
-
-## Alternatives Considered
-
-Non-Curses UI: This would help avoid dependence on libncurses, which some BMCs
-might not have. However, we expect libncurses to be present on most BMCs because
-it is widely used in most TUIs.
-
-## Impacts
-
-API impact: none
-
-Security impact: Being confirmed.
-
-Performance impact: Will only have a small impact when the program is running.
-No impact when it’s not running.
-
-Developer impact: For machines that do not install libncurses by default, adding
-this tool might incur a ~130KB overhead due to the libncurses library. No space
-overhead if the machine already includes libncurses.
-
-## Testing
-
-Individual functionalities will be tested with unit tests.
-
-Functional tests will be done using PCAP files.
-
-CI testing is not affected since it doesn’t modify the build process of any
-other package.
diff --git a/dbus-top/analyzer.cpp b/dbus-top/analyzer.cpp
deleted file mode 100644
index f31868c..0000000
--- a/dbus-top/analyzer.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-// 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
deleted file mode 100644
index 2284c7f..0000000
--- a/dbus-top/analyzer.hpp
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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
deleted file mode 100644
index 36f34a1..0000000
--- a/dbus-top/bargraph.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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
deleted file mode 100644
index 715fd41..0000000
--- a/dbus-top/dbus_capture.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-// 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
deleted file mode 100644
index 825a519..0000000
--- a/dbus-top/dbus_capture.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
deleted file mode 100644
index 4de4f0e..0000000
--- a/dbus-top/dbus_top_recipe.bb
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index 750a9f4..0000000
--- a/dbus-top/histogram.hpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// 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
deleted file mode 100644
index 5293f9b..0000000
--- a/dbus-top/main.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-// 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)
-        {
-            mvwaddstr(win, y, x, txt.substr(0, width).c_str());
-            txt = txt.substr(width);
-        }
-        else
-        {
-            mvwaddstr(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
deleted file mode 100644
index 91c07da..0000000
--- a/dbus-top/main.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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
deleted file mode 100644
index 47d1f57..0000000
--- a/dbus-top/menu.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-// 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(' ');
-            }
-            mvwaddstr(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;
-}
diff --git a/dbus-top/menu.hpp b/dbus-top/menu.hpp
deleted file mode 100644
index afb4110..0000000
--- a/dbus-top/menu.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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
deleted file mode 100644
index 60d4641..0000000
--- a/dbus-top/meson.build
+++ /dev/null
@@ -1,48 +0,0 @@
-# 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
deleted file mode 100644
index aa7bf89..0000000
--- a/dbus-top/rect.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3f8bba6..0000000
--- a/dbus-top/sensorhelper.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-// 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
deleted file mode 100644
index a619c4a..0000000
--- a/dbus-top/sensorhelper.hpp
+++ /dev/null
@@ -1,342 +0,0 @@
-// 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
deleted file mode 100644
index 6847ae5..0000000
--- a/dbus-top/subprojects/fmt.wrap
+++ /dev/null
@@ -1,3 +0,0 @@
-[wrap-git]
-url = https://github.com/fmtlib/fmt
-revision = HEAD
diff --git a/dbus-top/subprojects/sdbusplus.wrap b/dbus-top/subprojects/sdbusplus.wrap
deleted file mode 100644
index 7b076d0..0000000
--- a/dbus-top/subprojects/sdbusplus.wrap
+++ /dev/null
@@ -1,6 +0,0 @@
-[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
deleted file mode 100644
index fdbf85d..0000000
--- a/dbus-top/views.cpp
+++ /dev/null
@@ -1,1236 +0,0 @@
-// 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(' ');
-                    }
-                }
-                mvwaddstr(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
-        {
-            mvwaddstr(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, '-');
-        }
-        mvwaddstr(win, y1 - 3, arrow_x - 8, "Press [Enter] to show/hide");
-        mvwaddstr(win, y1 - 2, caption_x - 5,
-                  "DBus fields for aggregating and sorting results:");
-        if (curr_menu_state_ == LeftSide)
-        {
-            mvwaddstr(win, y1 - 1, x1 - 4, "--[ Available Fields ]--");
-            mvwaddstr(win, y1 - 1, x2 - 4, "--- Active Fields ---");
-        }
-        else
-        {
-            mvwaddstr(win, y1 - 1, x1 - 4, "--- Available Fields ---");
-            mvwaddstr(win, y1 - 1, x2 - 4, "--[ Active Fields ]--");
-        }
-        if (curr_menu_state_ == LeftSide)
-        {
-            mvwaddstr(win, arrow_y, arrow_x, "-->");
-            mvwaddstr(win, caption_y, caption_x,
-                      "Press [Space] to move to the right");
-        }
-        else
-        {
-            mvwaddstr(win, arrow_y, arrow_x, "<--");
-            mvwaddstr(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
deleted file mode 100644
index d4f3779..0000000
--- a/dbus-top/views.hpp
+++ /dev/null
@@ -1,539 +0,0 @@
-// 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
deleted file mode 100644
index 2e4b1a3..0000000
--- a/dbus-top/xmlparse.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-// 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
deleted file mode 100644
index 3a76e9a..0000000
--- a/dbus-top/xmlparse.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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);
