diff --git a/dbus-top/views.cpp b/dbus-top/views.cpp
new file mode 100644
index 0000000..0e6f8b0
--- /dev/null
+++ b/dbus-top/views.cpp
@@ -0,0 +1,1236 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "views.hpp"
+#include "bargraph.hpp"
+#include "histogram.hpp"
+#include "menu.hpp"
+#include <string.h>
+#include <algorithm>
+
+extern SensorSnapshot* g_sensor_snapshot;
+extern BarGraph<float>* g_bargraph;
+extern DBusTopStatistics* g_dbus_statistics;
+extern Histogram<float>* g_histogram;
+extern DBusTopWindow* g_current_active_view;
+extern const std::string FieldNames[];
+extern const int FieldPreferredWidths[];
+
+namespace dbus_top_analyzer
+{
+    extern DBusTopStatistics g_dbus_statistics;
+}
+
+// Linear interpolation
+float Lerp(float a, float b, float t)
+{
+    return a + t * (b - a);
+}
+
+// Linear map
+float Map(float value, float start1, float stop1, float start2, float stop2,
+          bool within_bounds)
+{
+    float t = (value - start1) / (stop1 - start1);
+    float ret = Lerp(start2, stop2, t);
+    if (within_bounds)
+    {
+        if (ret < start2)
+            ret = start2;
+        if (ret > stop2)
+            ret = stop2;
+    }
+    return ret;
+}
+
+template <typename T>
+void HistoryBarGraph(WINDOW* win, const Rect& rect, BarGraph<T>* bargraph)
+{
+    const int RIGHT_MARGIN = 5;
+    const int x0 = rect.x, y0 = 2;
+    const int w = rect.w - 2 - RIGHT_MARGIN;
+    const int h = rect.h - 3; // height of content
+    wattrset(win, 0);
+    wattron(win, A_BOLD | A_UNDERLINE);
+    mvwaddstr(win, 1, x0, "History     (Total msg/s)");
+    wattrset(win, 0);
+    // 1. Obtain data, determine Y range
+    std::vector<float> data = bargraph->GetLastNValues(w - RIGHT_MARGIN - 1);
+    float ymax = -1e20, ymin = 1e20;
+    if (data.empty())
+    {
+        data.push_back(0);
+        ymin = 0;
+        ymax = 10;
+    }
+    else
+    {
+        for (const float x : data)
+        {
+            ymax = std::max(ymax, x);
+            ymin = std::min(ymin, x);
+        }
+    }
+    // Fix edge case for both == 0
+    float diff = ymax - ymin;
+    if (diff < 0)
+    {
+        diff = -diff;
+    }
+    const float EPS = 1e-4;
+    if (diff < EPS)
+    {
+        ymax += 10;
+        ymin -= 10;
+    }
+    // Choose a suitable round-up unit to snap the grid labels to
+    int snap = 1;
+    if (ymax < 100)
+    {
+        snap = 10;
+    }
+    else if (ymax < 10000)
+    {
+        snap = 100;
+    }
+    else
+    {
+        snap = 1000;
+    }
+    const float eps = snap / 100.0f;
+    int label_ymax =
+        (static_cast<int>((ymax - eps) / snap) + 1) * snap; // round up
+    int label_ymin = static_cast<int>(ymin / snap) * snap;  // round down
+    float y_per_row = (label_ymax - label_ymin) * 1.0f / (h - 1);
+    int actual_ymax = label_ymax + static_cast<int>(y_per_row / 2);
+    int actual_ymin = label_ymin - static_cast<int>(y_per_row / 2);
+    // 2. Print Y axis ticks
+    for (int i = 0; i < h; i++)
+    {
+        char buf[10];
+        snprintf(
+            buf, sizeof(buf), "%-6d",
+            static_cast<int>(Lerp(label_ymax, label_ymin, i * 1.0f / (h - 1))));
+        mvwaddstr(win, i + y0, x0 + w - RIGHT_MARGIN + 1, buf);
+        mvwaddch(win, i + y0, x0, '-');
+        mvwaddch(win, i + y0, x0 + w - RIGHT_MARGIN, '-');
+    }
+    // 3. Go through the historical data and draw on the canvas
+    for (int i = 0;
+         i < std::min(static_cast<int>(data.size()), w - RIGHT_MARGIN - 1); i++)
+    {
+        float value = data[i];
+        // antialiasing: todo for now
+        // float value1 = value; // value1 is 1 column to the right
+        // if (i > 0) value1 = data[i-1];
+        int x = x0 + w - i - RIGHT_MARGIN - 1;
+        float t = Map(value, actual_ymin, actual_ymax, 0, h, true);
+        int row = static_cast<int>(t);
+        float remaining = t - row;
+        char ch; // Last filling character
+        if (remaining >= 0.66f)
+        {
+            ch = ':';
+        }
+        else if (remaining >= 0.33f)
+        {
+            ch = '.';
+        }
+        else
+        {
+            ch = ' ';
+        }
+        int y = y0 + h - row - 1;
+        mvwaddch(win, y, x, ch);
+        for (int j = 0; j < row; j++)
+        {
+            mvwaddch(win, y + j + 1, x, ':');
+        }
+    }
+}
+
+template <typename T>
+void DrawHistogram(WINDOW* win, const Rect& rect, Histogram<T>* histogram)
+{
+    // const int MARGIN = 7;  // 5 digits margin
+    const int LEFT_MARGIN = 7;
+    // const int max_bucket_h = histogram->MaxBucketHeight();
+    const int H_PAD = 0, V_PAD = 1;
+    // x0, x1, y0 and y1 are the bounding box of the contents to be printed
+    const int x0 = rect.x + H_PAD;
+    const int x1 = rect.x + rect.w - H_PAD;
+    const int y0 = rect.y + V_PAD;
+    const int y1 = rect.y + rect.h - 1 - V_PAD;
+    // Title
+    wattron(win, A_BOLD | A_UNDERLINE);
+    mvwaddstr(win, y0, x0, "Method Call Time (us) Histogram");
+    wattrset(win, 0);
+    // x2 is the beginning X of the histogram itself (not containing the margin)
+    const int x2 = x0 + LEFT_MARGIN;
+    if (histogram->Empty())
+    {
+        mvwaddstr(win, (y1 + y0) / 2, (x0 + x1) / 2, "(Empty)");
+        return;
+    }
+    histogram->SetBucketCount(x1 - x2 + 1);
+    histogram->ComputeHistogram();
+    // Draw X axis labels
+    char buf[22];
+    snprintf(buf, sizeof(buf), "%.2f",
+             static_cast<float>(histogram->LowPercentile()));
+    mvwaddstr(win, y1, x0 + LEFT_MARGIN, buf);
+    snprintf(buf, sizeof(buf), "%.2f",
+             static_cast<float>(histogram->HighPercentile()));
+    mvwaddstr(win, y1, x1 + 1 - strlen(buf), buf);
+    snprintf(buf, sizeof(buf), "%d%%-%d%%",
+             static_cast<int>(histogram->LowCumDensity() * 100),
+             static_cast<int>(histogram->HighCumDensity() * 100));
+    mvwaddstr(win, y1, x0, buf);
+    // Draw Y axis labels
+    const float hist_ymax = y1 - 1;
+    const float hist_ymin = y0 + 1;
+    const int max_histogram_h = histogram->MaxBucketHeight();
+    if (hist_ymax <= hist_ymin)
+        return; // Not enough space for rendering
+    if (max_histogram_h <= 0)
+        return;
+    bool LOG_TRANSFORM = true;
+    float lg_maxh = 0;
+    if (LOG_TRANSFORM)
+    {
+        lg_maxh = log(max_histogram_h);
+    }
+    for (int y = hist_ymin; y <= hist_ymax; y++)
+    {
+        // There are (hist_ymax - hist_ymin + 1) divisions
+        float fullness;
+        fullness = (hist_ymax - y + 1) * 1.0f / (hist_ymax - hist_ymin + 1);
+        int h;
+        if (!LOG_TRANSFORM)
+        {
+            h = static_cast<int>(max_histogram_h * fullness);
+        }
+        else
+        {
+            h = static_cast<int>(exp(fullness * lg_maxh));
+        }
+        snprintf(buf, sizeof(buf), "%6d-", h);
+        mvwaddstr(win, y, x0 + LEFT_MARGIN - strlen(buf), buf);
+    }
+    const int bar_height = hist_ymax - hist_ymin + 1; // Height of a full bar
+    for (int x = x2, bidx = 0; x <= x1; x++, bidx++)
+    {
+        int h = histogram->BucketHeight(bidx);
+        float lines_visible;
+        if (!LOG_TRANSFORM)
+        {
+            lines_visible = h * 1.0f / max_histogram_h * bar_height;
+        }
+        else
+        {
+            if (h <= 0)
+                lines_visible = 0;
+            else
+                lines_visible = log(h) * 1.0f / lg_maxh * bar_height;
+        }
+        // The histogram's top shall start from this line
+        int y = hist_ymax - static_cast<int>(lines_visible);
+        float y_frac = lines_visible - static_cast<int>(lines_visible);
+        char ch; // Last filling character
+        if (y >= hist_ymin)
+        { // At the maximum bucket the Y overflows, so skip
+            if (y_frac >= 0.66f)
+            {
+                ch = ':';
+            }
+            else if (y_frac >= 0.33f)
+            {
+                ch = '.';
+            }
+            else
+            {
+                if (y < hist_ymax)
+                {
+                    ch = ' ';
+                }
+                else
+                {
+                    if (y_frac > 0)
+                    {
+                        ch =
+                            '.'; // Makes long-tailed distribution easier to see
+                    }
+                }
+            }
+            mvwaddch(win, y, x, ch);
+        }
+        y++;
+        for (; y <= hist_ymax; y++)
+        {
+            mvwaddch(win, y, x, ':');
+        }
+    }
+}
+
+void SummaryView::UpdateDBusTopStatistics(DBusTopStatistics* stat)
+{
+    if (!stat)
+        return;
+    float interval_secs = stat->seconds_since_last_sample_;
+    if (interval_secs == 0)
+    {
+        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
+    }
+    // Per-second
+    method_call_ = stat->num_mc_ / interval_secs;
+    method_return_ = stat->num_mr_ / interval_secs;
+    signal_ = stat->num_sig_ / interval_secs;
+    error_ = stat->num_error_ / interval_secs;
+    total_ = stat->num_messages_ / interval_secs;
+    g_bargraph->AddValue(total_);
+}
+
+std::string Ellipsize(const std::string& s, int len_limit)
+{
+    if (len_limit <= 3)
+        return s.substr(0, len_limit);
+    if (static_cast<int>(s.size()) < len_limit)
+    {
+        return s;
+    }
+    else
+    {
+        return s.substr(0, len_limit - 3) + "...";
+    }
+}
+
+void SummaryView::Render()
+{
+    // Draw text
+    werase(win);
+    if (!visible_)
+        return;
+    wattron(win, A_BOLD | A_UNDERLINE);
+    mvwaddstr(win, 1, 1, "Message Type          | msg/s");
+    wattrset(win, 0);
+    const int xend = 30;
+    std::string s;
+    s = FloatToString(method_call_);
+    mvwaddstr(win, 2, 1, "Method Call");
+    mvwaddstr(win, 2, xend - s.size(), s.c_str());
+    s = FloatToString(method_return_);
+    mvwaddstr(win, 3, 1, "Method Return ");
+    mvwaddstr(win, 3, xend - s.size(), s.c_str());
+    s = FloatToString(signal_);
+    mvwaddstr(win, 4, 1, "Signal");
+    mvwaddstr(win, 4, xend - s.size(), s.c_str());
+    s = FloatToString(error_);
+    mvwaddstr(win, 5, 1, "Error ");
+    mvwaddstr(win, 5, xend - s.size(), s.c_str());
+    wattron(win, A_UNDERLINE);
+    s = FloatToString(total_);
+    mvwaddstr(win, 6, 1, "Total");
+    mvwaddstr(win, 6, xend - s.size(), s.c_str());
+    wattroff(win, A_UNDERLINE);
+    wattrset(win, 0);
+    // Draw history bar graph
+    Rect bargraph_rect = rect;
+    const int bargraph_x = 64;
+    bargraph_rect.x += bargraph_x;
+    bargraph_rect.w -= bargraph_x;
+    HistoryBarGraph(win, bargraph_rect, g_bargraph);
+    // Draw histogram
+    Rect histogram_rect = rect;
+    histogram_rect.x += 32;
+    histogram_rect.w = bargraph_rect.x - histogram_rect.x - 3;
+    DrawHistogram(win, histogram_rect, g_histogram);
+    // Draw border between summary and histogram
+    for (int y = bargraph_rect.y; y <= bargraph_rect.y + bargraph_rect.h; y++)
+    {
+        mvwaddch(win, y, histogram_rect.x - 1, '|');
+        mvwaddch(win, y, bargraph_rect.x - 1, '|');
+    }
+    DrawBorderIfNeeded();
+    wrefresh(win);
+}
+
+void SensorDetailView::Render()
+{
+    werase(win);
+    if (!visible_)
+        return;
+    // If some sensor is focused, show details regarding that sensor
+    if (state == SensorList)
+    { // Otherwise show the complete list
+        const int ncols = DispSensorsPerRow(); // Number of columns in viewport
+        const int nrows = DispSensorsPerColumn(); // # rows in viewport
+        int sensors_per_page = nrows * ncols;
+        // Just in case the window gets invisibly small
+        if (sensors_per_page < 1)
+            return;
+        int num_sensors = sensor_ids_.size();
+        int total_num_columns = (num_sensors - 1) / nrows + 1;
+        bool is_cursor_out_of_view = false;
+        if (idx0 > choice_ || idx1 <= choice_)
+        {
+            is_cursor_out_of_view = true;
+        }
+        if (idx0 == INVALID || idx1 == INVALID)
+        {
+            is_cursor_out_of_view = true;
+        }
+        if (is_cursor_out_of_view)
+        {
+            idx0 = 0, idx1 = sensors_per_page;
+        }
+        while (idx1 <= choice_)
+        {
+            idx0 += nrows;
+            idx1 += nrows;
+        }
+        const int y0 = 2; // to account for the border and info line
+        const int x0 = 4; // to account for the left overflow marks
+        int y = y0, x = x0;
+        for (int i = 0; i < sensors_per_page; i++)
+        {
+            int idx = idx0 + i;
+            if (idx < static_cast<int>(sensor_ids_.size()))
+            {
+                if (idx == choice_)
+                {
+                    wattrset(win, A_REVERSE);
+                }
+                std::string s = sensor_ids_[idx];
+                if (static_cast<int>(s.size()) > col_width) {
+                    s = s.substr(0, col_width - 2) + "..";
+                } else {
+                    while (static_cast<int>(s.size()) < col_width)
+                    {
+                        s.push_back(' ');
+                    }
+                }
+                mvwprintw(win, y, x, s.c_str());
+                wattrset(win, 0);
+            }
+            else
+                break;
+            y++;
+            if (i % nrows == nrows - 1)
+            {
+                y = y0;
+                x += col_width + h_spacing;
+            }
+        }
+        // Print overflow marks to the right of the screen
+        for (int i = 0; i < nrows; i++)
+        {
+            int idx = idx0 + sensors_per_page + i;
+            if (idx < num_sensors)
+            {
+                mvwaddch(win, y0 + i, x, '>');
+            }
+        }
+        // Print overflow marks to the left of the screen
+        for (int i = 0; i < nrows; i++)
+        {
+            int idx = idx0 - nrows + i;
+            if (idx >= 0)
+            {
+                mvwaddch(win, y0 + i, 2, '<');
+            }
+        }
+        // idx1 is one past the visible range, so no need to +1
+        const int col0 = idx0 / nrows + 1, col1 = idx1 / nrows;
+        mvwprintw(win, 1, 2, "Columns %d-%d of %d", col0, col1,
+                  total_num_columns);
+        mvwprintw(win, 1, rect.w - 15, "%d sensors", sensor_ids_.size());
+    }
+    else if (state == SensorDetail)
+    {
+        // sensor_ids_ is the cached list of sensors, it should be the same size
+        // as the actual number of sensors in the snapshot
+        mvwprintw(win, 1, 2, "Details of sensor %s", curr_sensor_id_.c_str());
+        mvwprintw(win, 1, rect.w - 15, "Sensor %d/%u", choice_ + 1,
+                  sensor_ids_.size()); // 1-based
+        std::vector<Sensor*> sensors =
+            g_sensor_snapshot->FindSensorsBySensorID(curr_sensor_id_);
+        const int N = static_cast<int>(sensors.size());
+        const int w = rect.w - 5;
+        mvwprintw(win, 3, 2, "There are %d sensors with the name %s", N,
+                  curr_sensor_id_.c_str());
+        int y = 5;
+        int x = 2;
+        if (N > 0)
+        {
+            for (int j = 0; j < N; j++)
+            {
+                Sensor* sensor = sensors[j];
+                mvwprintw(win, y, x, "%d/%d", j + 1, N);
+                char buf[200];
+                snprintf(buf, sizeof(buf), "DBus Service    : %s",
+                         sensor->ServiceName().c_str());
+                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
+                snprintf(buf, sizeof(buf), "DBus Connection : %s",
+                         sensor->ConnectionName().c_str());
+                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
+                snprintf(buf, sizeof(buf), "DBus Object Path: %s",
+                         sensor->ObjectPath().c_str());
+                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
+                y++;
+            }
+        }
+        else
+        {
+            mvwprintw(win, y, x, "Sensor details not found");
+        }
+    }
+    DrawBorderIfNeeded();
+    wrefresh(win);
+}
+
+std::string SensorDetailView::GetStatusString()
+{
+    if (state == SensorList)
+    {
+        return "[Arrow Keys]=Move Cursor [Q]=Deselect [Enter]=Show Sensor "
+               "Detail";
+    }
+    else
+    {
+        return "[Arrow Keys]=Cycle Through Sensors [Esc/Q]=Exit";
+    }
+}
+
+DBusStatListView::DBusStatListView() : DBusTopWindow()
+{
+    highlight_col_idx_ = 0;
+    sort_col_idx_ = 0;
+    sort_order_ = SortOrder::Ascending;
+    horizontal_pan_ = 0;
+    row_idx_ = INVALID;
+    disp_row_idx_ = 0;
+    horizontal_pan_ = 0;
+    menu1_ = new ArrowKeyNavigationMenu(this);
+    menu2_ = new ArrowKeyNavigationMenu(this);
+    // Load all available field names
+    std::set<std::string> inactive_fields;
+    std::set<std::string> active_fields;
+
+    // Default choice of field names
+    const int N = static_cast<int>(sizeof(FieldNames) / sizeof(FieldNames[0]));
+    for (int i = 0; i < N; i++)
+    {
+        inactive_fields.insert(FieldNames[i]);
+    }
+    for (const std::string& s :
+         dbus_top_analyzer::g_dbus_statistics.GetFieldNames())
+    {
+        inactive_fields.erase(s);
+        active_fields.insert(s);
+    }
+    for (int i = 0; i < N; i++)
+    {
+    const std::string s = FieldNames[i];
+        if (inactive_fields.count(s) > 0)
+        {
+            menu1_->AddItem(s);
+        }
+        else
+        {
+            menu2_->AddItem(s);
+        }
+    }
+    
+    curr_menu_state_ = LeftSide;
+    menu_h_ = 5;
+    menu_w_ = 24; // Need at least 2*padding + 15 for enough space, see menu.hpp
+    menu_margin_ = 6;
+    // Populate preferred column widths
+    for (int i = 0; i < N; i++)
+    {
+        column_widths_[FieldNames[i]] = FieldPreferredWidths[i];
+    }
+}
+
+std::pair<int, int> DBusStatListView::GetXSpanForColumn(const int col_idx)
+{
+    std::vector<int> cw = ColumnWidths();
+    if (col_idx < 0 || col_idx >= static_cast<int>(cw.size()))
+    {
+        return std::make_pair(INVALID, INVALID);
+    }
+    int x0 = 0, x1 = 0;
+    for (int i = 0; i < col_idx; i++)
+    {
+        if (i > 0)
+        {
+            x0 += cw[i];
+        }
+    }
+    x1 = x0 + cw[col_idx] - 1;
+    return std::make_pair(x0, x1);
+}
+
+// If tolerance > 0, consider overlap before 2 intervals intersect
+// If tolerance ==0, consider overlap if 2 intervals exactly intersect
+// If tolerance < 0, consider overlap if Minimal Translate Distance is >=
+// -threshold
+bool IsSpansOverlap(const std::pair<int, int>& s0,
+                    const std::pair<int, int>& s1, int tolerance)
+{
+    if (tolerance >= 0)
+    {
+        if (s0.second < s1.first - tolerance)
+            return false;
+        else if (s1.second < s0.first - tolerance)
+            return false;
+        else
+            return true;
+    }
+    else
+    {
+        // Compute overlapping distance
+        std::vector<std::pair<int, int>> tmp(
+            4); // [x, 1] means the start of interval
+                // [x,-1] means the end of interval
+        tmp[0] = std::make_pair(s0.first, 1);
+        tmp[1] = std::make_pair(s0.second, -1);
+        tmp[2] = std::make_pair(s1.first, 1);
+        tmp[3] = std::make_pair(s1.second, -1);
+        std::sort(tmp.begin(), tmp.end());
+        int overlap_x0 = -INVALID, overlap_x1 = -INVALID;
+        int idx = 0;
+        const int N = static_cast<int>(tmp.size());
+        int level = 0;
+        while (idx < N)
+        {
+            const int x = tmp[idx].first;
+            while (idx < N && x == tmp[idx].first)
+            {
+                level += tmp[idx].second;
+                idx++;
+            }
+            // The starting position of the overlap
+            if (level == 2)
+            {
+                overlap_x0 = idx - 1;
+            }
+            // The ending position of the overlap
+            if (overlap_x0 != -INVALID && level < 2 && overlap_x1 == -INVALID)
+            {
+                overlap_x1 = idx - 1;
+            }
+        }
+        const int overlap_length = overlap_x1 - overlap_x0 + 1;
+        if (overlap_length >= -tolerance)
+            return true;
+        else
+            return false;
+    }
+}
+
+bool DBusStatListView::IsXSpanVisible(const std::pair<int, int>& xs,
+                                      int tolerance)
+{
+    const std::pair<int, int> vxs = {horizontal_pan_, horizontal_pan_ + rect.w};
+    return IsSpansOverlap(xs, vxs, tolerance);
+}
+std::vector<std::string> DBusStatListView::ColumnHeaders()
+{
+    return visible_columns_;
+}
+
+std::vector<int> DBusStatListView::ColumnWidths()
+{
+    std::vector<int> widths = {8}; // for "Msg/s"
+    std::vector<std::string> agg_headers = visible_columns_;
+    std::vector<int> agg_widths(agg_headers.size(), 0);
+    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
+    {
+        agg_widths[i] = column_widths_[agg_headers[i]];
+    }
+    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
+    return widths;
+}
+
+// Coordinate systems are in world space, +x faces to the right
+// Viewport:            [horizontal_pan_,   horizontal_pan_ + rect.w]
+// Contents:  [  column_width[0]  ][  column_width[1] ][  column_width[2]  ]
+void DBusStatListView::PanViewportOrMoveHighlightedColumn(const int delta_x)
+{
+    // If the column to the left is visible, highlight it
+    const int N = static_cast<int>(ColumnHeaders().size());
+    bool col_idx_changed = false;
+    if (delta_x < 0)
+    { // Pan left
+        if (highlight_col_idx_ > 0)
+        {
+            std::pair<int, int> xs_left =
+                GetXSpanForColumn(highlight_col_idx_ - 1);
+            if (IsXSpanVisible(xs_left, -1))
+            {
+                highlight_col_idx_--;
+                col_idx_changed = true;
+            }
+        }
+        if (!col_idx_changed)
+        {
+            horizontal_pan_ += delta_x;
+        }
+    }
+    else if (delta_x > 0)
+    { // Pan right
+        if (highlight_col_idx_ < N - 1)
+        {
+            std::pair<int, int> xs_right =
+                GetXSpanForColumn(highlight_col_idx_ + 1);
+            if (IsXSpanVisible(xs_right, -1))
+            {
+                highlight_col_idx_++;
+                col_idx_changed = true;
+            }
+        }
+        if (!col_idx_changed)
+        {
+            horizontal_pan_ += delta_x;
+        }
+    }
+}
+
+void DBusStatListView::OnKeyDown(const std::string& key)
+{
+    {
+        switch (curr_menu_state_)
+        {
+            case LeftSide:
+            {
+                if (key == "up")
+                {
+                    menu1_->OnKeyDown("up");
+                }
+                else if (key == "down")
+                {
+                    menu1_->OnKeyDown("down");
+                }
+                else if (key == "right")
+                {
+                    SetMenuState(RightSide);
+                }
+                else if (key == "enter")
+                {
+                    SetMenuState(Hidden);
+                }
+                else if (key == "space")
+                {
+                    std::string ch;
+                    if (menu1_->RemoveHighlightedItem(&ch))
+                    {
+                        menu2_->AddItem(ch);
+                    }
+                }
+                break;
+            }
+            case RightSide:
+            {
+                if (key == "up")
+                {
+                    menu2_->OnKeyDown("up");
+                }
+                else if (key == "down")
+                {
+                    menu2_->OnKeyDown("down");
+                }
+                else if (key == "left")
+                {
+                    SetMenuState(LeftSide);
+                }
+                else if (key == "enter")
+                {
+                    SetMenuState(Hidden);
+                }
+                else if (key == "space")
+                {
+                    std::string ch;
+                    if (menu2_->RemoveHighlightedItem(&ch))
+                    {
+                        menu1_->AddItem(ch);
+                    }
+                }
+                break;
+            }
+            case Hidden:
+            {
+                if (key == "enter")
+                {
+                    switch (last_menu_state_)
+                    {
+                        case LeftSide:
+                        case RightSide:
+                            SetMenuState(last_menu_state_);
+                            break;
+                        default:
+                            SetMenuState(LeftSide);
+                    }
+                }
+                else if (key == "left")
+                {
+                    PanViewportOrMoveHighlightedColumn(-2);
+                }
+                else if (key == "right")
+                {
+                    PanViewportOrMoveHighlightedColumn(2);
+                }
+                else if (key == "up")
+                {
+                    disp_row_idx_--;
+                    if (disp_row_idx_ < 0)
+                    {
+                        disp_row_idx_ = 0;
+                    }
+                }
+                else if (key == "down")
+                {
+                    disp_row_idx_++;
+                    const int N = static_cast<int>(stats_snapshot_.size());
+                    if (disp_row_idx_ >= N)
+                    {
+                        disp_row_idx_ = N - 1;
+                    }
+                }
+                else if (key == "a")
+                {
+                    sort_order_ = SortOrder::Ascending;
+                    sort_col_idx_ = highlight_col_idx_;
+                    break;
+                }
+                else if (key == "d")
+                {
+                    sort_order_ = SortOrder::Descending;
+                    sort_col_idx_ = highlight_col_idx_;
+                    break;
+                }
+                break;
+            }
+        }
+    }
+    Render();
+}
+
+// Window C
+void DBusStatListView::Render()
+{
+    werase(win);
+    if (!visible_)
+        return;
+    int num_lines_shown = rect.h - 3;
+    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
+    {
+        menu1_->Render();
+        menu2_->Render();
+        num_lines_shown -= (menu_h_ + 3);
+        // Draw the arrow
+        const int x1 = menu1_->rect_.x;
+        const int h1 = menu1_->rect_.h;
+        const int x2 = menu2_->rect_.x;
+        const int w2 = menu2_->rect_.w;
+        const int y1 = menu1_->rect_.y;
+        const int arrow_x = (x1 + x2 + w2) / 2 - 2;
+        const int arrow_y = y1 + 2;
+        const int caption_x = x1;
+        const int caption_y = y1 + h1;
+        for (int x = 1; x < rect.w - 1; x++)
+        {
+            mvwaddch(win, y1 - 3, x, '-');
+        }
+        mvwprintw(win, y1 - 3, arrow_x - 8, "Press [Enter] to show/hide");
+        mvwprintw(win, y1 - 2, caption_x - 5,
+                  "DBus fields for aggregating and sorting results:");
+        if (curr_menu_state_ == LeftSide)
+        {
+            mvwprintw(win, y1 - 1, x1 - 4, "--[ Available Fields ]--");
+            mvwprintw(win, y1 - 1, x2 - 4, "--- Active Fields ---");
+        }
+        else
+        {
+            mvwprintw(win, y1 - 1, x1 - 4, "--- Available Fields ---");
+            mvwprintw(win, y1 - 1, x2 - 4, "--[ Active Fields ]--");
+        }
+        if (curr_menu_state_ == LeftSide)
+        {
+            mvwprintw(win, arrow_y, arrow_x, "-->");
+            mvwprintw(win, caption_y, caption_x,
+                      "Press [Space] to move to the right");
+        }
+        else
+        {
+            mvwprintw(win, arrow_y, arrow_x, "<--");
+            mvwprintw(win, caption_y, caption_x,
+                      "Press [Space] to move to the left");
+        }
+    }
+    std::vector<std::string> headers;
+    std::vector<int> widths;
+    visible_columns_ = g_dbus_statistics->GetFieldNames();
+    std::vector<std::string> agg_headers = visible_columns_;
+    std::vector<int> agg_widths(agg_headers.size(), 0);
+    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
+    {
+        agg_widths[i] = column_widths_[agg_headers[i]];
+    }
+    headers.insert(headers.end(), agg_headers.begin(), agg_headers.end());
+    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
+    std::vector<int> xs;
+    int curr_x = 2 - horizontal_pan_;
+    for (const int w : widths)
+    {
+        xs.push_back(curr_x);
+        curr_x += w;
+    }
+    const int N = headers.size();
+    // Bound col_idx_
+    if (highlight_col_idx_ >= N)
+    {
+        highlight_col_idx_ = N - 1;
+    }
+    // Render column headers
+    for (int i = 0; i < N; i++)
+    {
+        std::string s = headers[i];
+        // 1 char outside boundary = start printing from the second character,
+        // etc
+
+        // Print "<" for Ascending order (meaning: row 0 < row 1 < row 2 ... )
+        // Print ">" for Descending order (meaning: row 0 > row 1 > row 2 ... )
+        if (sort_col_idx_ == i)
+        {
+            if (sort_order_ == SortOrder::Ascending)
+            {
+                s.push_back('<');
+            }
+            else
+            {
+                s.push_back('>');
+            }
+        }
+
+        // Highlight the "currently-selected column"
+        if (highlight_col_idx_ == i)
+        {
+            wattrset(win, 0);
+            wattron(win, A_REVERSE);
+        }
+        else
+        {
+            wattrset(win, 0);
+            wattron(win, A_UNDERLINE);
+        }
+        int x = xs[i];
+        if (x < 0)
+        {
+            if (-x < static_cast<int>(s.size()))
+            {
+                s = s.substr(-x);
+            }
+            else
+                s = "";
+            x = 0;
+        }
+        mvwaddstr(win, 1, x, s.c_str());
+    }
+    wattrset(win, 0);
+    // Time since the last update of Window C
+    float interval_secs = g_dbus_statistics->seconds_since_last_sample_;
+    if (interval_secs == 0)
+    {
+        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
+    }
+
+    stats_snapshot_ = g_dbus_statistics->StatsSnapshot();
+    const int nrows = static_cast<int>(stats_snapshot_.size());
+    const std::vector<DBusTopSortField> fields = g_dbus_statistics->GetFields();
+    const int ncols = static_cast<int>(fields.size());
+    // Merge the list of DBus Message properties & computed metrics together
+    std::map<std::vector<std::string>, DBusTopComputedMetrics>::iterator itr =
+        stats_snapshot_.begin();
+    struct StringOrFloat
+    { // Cannot use union so using struct
+        std::string s;
+        float f;
+    };
+
+    // "Stage" the snapshot for displaying in the form of a spreadsheet
+    std::vector<std::pair<StringOrFloat, std::vector<std::string>>>
+        stats_snapshot_staged;
+    const DBusTopSortField sort_field = fields[sort_col_idx_];
+    const bool is_sort_key_numeric = DBusTopSortFieldIsNumeric(sort_field);
+
+    for (int i = 0; i < nrows; i++) // One row of cells
+    {
+        int idx0 = 0; // indexing into the std::vector<string> of each row
+        std::vector<std::string> row;
+
+        StringOrFloat sort_key; // The key used for sorting
+        for (int j = 0; j < ncols; j++) // one column in the row
+        {
+            DBusTopSortField field = fields[j];
+            // Populate the content of stats_snapshot_staged
+
+            StringOrFloat sof; // Represents this column
+            
+            // When we haven't used up all
+            if (idx0 < static_cast<int>(itr->first.size()))
+            {
+                sof.s = itr->first[idx0];
+            }
+            switch (field)
+            {
+                case kSender:      // string
+                case kDestination: // string
+                case kInterface:   // string
+                case kPath:        // string
+                case kMember:      // string
+                case kSenderPID:   // numeric
+                case kSenderCMD:   // string
+                    row.push_back(itr->first[idx0]);
+                    idx0++;
+                    if (field == kSenderPID)
+                    {
+                        // Note: attempting to std::atof("(unknown)") on the BMC
+                        // will cause hang. And GDB won't show backtrace.
+                        if (sof.s == "(unknown)")
+                        {
+                            if (sort_order_ == Ascending)
+                            {
+                                sof.f = -1;
+                            }
+                            else
+                            {
+                                sof.f = 1e20;
+                            }
+                        }
+                        else
+                        {
+                            sof.f = std::atof(sof.s.c_str());
+                        }
+                    }
+                    break;
+                case kMsgPerSec: // Compute "messages per second"
+                {
+                    int numbers[] = {
+                        itr->second.num_method_calls,
+                        itr->second.num_method_returns,
+                        itr->second.num_signals,
+                        itr->second.num_errors,
+                    };
+                    int the_sum = 0; // For sorting
+
+                    std::string s; // String representation in the form or
+                                   // "1.00/2.00/3.00/4.00"
+                    for (int i = 0; i < 4; i++)
+                    {
+                        the_sum += numbers[i];
+                        if (i > 0)
+                            s += "/";
+                        float per_sec = numbers[i] / interval_secs;
+                        s += FloatToString(per_sec);
+                    }
+
+                    row.push_back(s);
+                    sof.f = the_sum;
+                    break;
+                }
+                case kAverageLatency: // Compute "average Method Call latency"
+                    const DBusTopComputedMetrics& m = itr->second;
+                    if (m.num_method_calls == 0)
+                    {
+                        row.push_back("n/a");
+                        if (sort_order_ == Ascending)
+                        {
+                            sof.f = -1; // Put to the top
+                        }
+                        else
+                        {
+                            sof.f = 1e20; // Put to the top
+                        }
+                    }
+                    else
+                    {
+                        float avg_latency_usec =
+                            m.total_latency_usec / m.num_method_calls;
+                        row.push_back(FloatToString(avg_latency_usec));
+                        sof.f = avg_latency_usec;
+                    }
+                    break;
+            }
+            if (j == sort_col_idx_)
+            {
+                sort_key = sof;
+            }
+        }
+        stats_snapshot_staged.push_back(std::make_pair(sort_key, row));
+        itr++;
+    }
+    
+    // Sort the "staged snapshot" using the sort_key, using different functions
+    // depending on whether sort key is numeric or string
+    if (is_sort_key_numeric)
+    {
+        std::sort(
+            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
+            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
+               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
+                return a.first.f < b.first.f;
+            });
+    }
+    else
+    {
+        std::sort(
+            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
+            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
+               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
+                return a.first.s < b.first.s;
+            });
+    }
+    
+    if (sort_order_ == Descending)
+    {
+        std::reverse(stats_snapshot_staged.begin(),
+                     stats_snapshot_staged.end());
+    }
+    // Minus 2 because of "msgs/s" and "+"
+    const int num_fields = N;
+    // The Y span of the area for rendering the "spreadsheet"
+    const int y0 = 2, y1 = y0 + num_lines_shown - 1;
+    // Key is sender, destination, interface, path, etc
+    for (int i = 0, shown = 0;
+        i + disp_row_idx_ < static_cast<int>(stats_snapshot_staged.size()) &&
+        shown < num_lines_shown;
+        i++, shown++)
+    {
+        std::string s;
+        int x = 0;
+        const std::vector<std::string> key =
+            stats_snapshot_staged[i + disp_row_idx_].second;
+        for (int j = 0; j < num_fields; j++)
+        {
+            x = xs[j];
+            s = key[j];
+            // Determine column width limit for this particular column
+            int col_width = 100;
+            if (j < num_fields - 1)
+            {
+                col_width = xs[j + 1] - xs[j] - 1;
+            }
+            s = Ellipsize(s, col_width);
+            if (x < 0)
+            {
+                if (-x < static_cast<int>(s.size()))
+                    s = s.substr(-x);
+                else
+                    s = "";
+                x = 0;
+            }
+            // Trim if string overflows to the right
+            if (x + static_cast<int>(s.size()) > rect.w)
+            {
+                s = s.substr(0, rect.w - x);
+            }
+            mvwaddstr(win, 2 + i, x, s.c_str());
+        }
+    }
+    // Overflows past the top ...
+    if (disp_row_idx_ > 0)
+    {
+        std::string x = " [+" + std::to_string(disp_row_idx_) + " rows above]";
+        mvwaddstr(win, y0, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
+    }
+    // Overflows past the bottom ...
+    const int last_disp_row_idx = disp_row_idx_ + num_lines_shown - 1;
+    if (last_disp_row_idx < nrows - 1)
+    {
+        std::string x = " [+" +
+                        std::to_string((nrows - 1) - last_disp_row_idx) +
+                        " rows below]";
+        mvwaddstr(win, y1, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
+    }
+    DrawBorderIfNeeded();
+    wrefresh(win);
+}
+
+void DBusStatListView::OnResize(int win_w, int win_h)
+{
+    rect.y = 8 - MARGIN_BOTTOM;
+    rect.w = win_w - (win_w / 2) + 1; // Perfectly overlap on the vertical edge
+    rect.x = win_w - rect.w;
+    rect.h = win_h - rect.y - MARGIN_BOTTOM;
+    const int x0 = rect.w / 2 - menu_w_ - menu_margin_ / 2;
+    const int x1 = x0 + menu_margin_ + menu_w_;
+    const int menu_y = rect.h - menu_h_;
+    menu1_->SetRect(Rect(x0, menu_y, menu_w_, menu_h_)); // Local coordinates
+    menu1_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
+    menu2_->SetRect(Rect(x1, menu_y, menu_w_, menu_h_));
+    menu2_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
+    UpdateWindowSizeAndPosition();
+}
+
+std::vector<DBusTopSortField> DBusStatListView::GetSortFields()
+{
+    std::vector<DBusTopSortField> ret;
+    const int N = sizeof(FieldNames) / sizeof(FieldNames[0]);
+    for (const std::string& s : menu2_->Items())
+    {
+        for (int i = 0; i < N; i++)
+        {
+            if (FieldNames[i] == s)
+            {
+                ret.push_back(static_cast<DBusTopSortField>(i));
+                break;
+            }
+        }
+    }
+    return ret;
+}
+
+std::string DBusStatListView::GetStatusString()
+{
+    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
+    {
+        return "[Enter]=Hide Panel [Space]=Choose Entry [Arrow Keys]=Move "
+               "Cursor";
+    }
+    else
+    {
+        return "[Enter]=Show Column Select Panel [Arrow Keys]=Pan View";
+    }
+}
+
+void FooterView::Render()
+{
+    werase(win);
+    const time_t now = time(nullptr);
+    const char* date_time = ctime(&now);
+    wattrset(win, 0);
+    std::string help_info;
+    if (g_current_active_view == nullptr)
+    {
+        help_info = "Press [Tab] to cycle through views";
+    }
+    else
+    {
+        help_info = g_current_active_view->GetStatusString();
+    }
+    mvwaddstr(win, 0, 1, date_time);
+    mvwaddstr(win, 0, rect.w - int(help_info.size()) - 1, help_info.c_str());
+    wrefresh(win);
+}
