public static Map<String, Object> getTopologySummary(TopologyPageInfo topologyPageInfo,
                                                         String window, Map<String, Object> config, String remoteUser) {
        Map<String, Object> result = new HashMap();
        Map<String, Object> topologyConf = (Map<String, Object>) JSONValue.parse(topologyPageInfo.get_topology_conf());
        int messageTimeout = (int) topologyConf.get(Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS);
        Map<String, Object> unpackedTopologyPageInfo =
                unpackTopologyInfo(topologyPageInfo, window, config);
        result.putAll(unpackedTopologyPageInfo);
        result.put("user", remoteUser);
        result.put("window", window);
        result.put("windowHint", getWindowHint(window));
        result.put("msgTimeout", messageTimeout);
        result.put("configuration", topologyConf);
        result.put("visualizationTable", new ArrayList());
        result.put("schedulerDisplayResource", config.get(DaemonConfig.SCHEDULER_DISPLAY_RESOURCE));
        result.put("bugtracker-url", config.get(DaemonConfig.UI_PROJECT_BUGTRACKER_URL));
        result.put("central-log-url", config.get(DaemonConfig.UI_CENTRAL_LOGGING_URL));
        return result;
    }
@Test
    void test_getTopologySpoutAggStatsMap_includesLastError() {
        // Define inputs
        final String expectedSpoutId = "MySpoutId";
        final String expectedErrorMsg = "This is my test error message";
        final int expectedErrorTime = Time.currentTimeSecs();
        final int errorElapsedTimeSecs = 13;
        final int expectedErrorElapsedTime = expectedErrorTime + errorElapsedTimeSecs;
        final int expectedErrorPort = 4321;
        final String expectedErrorHost = "my.errored.host";

        // Define our Last Error
        final ErrorInfo expectedLastError = new ErrorInfo(expectedErrorMsg, expectedErrorTime);
        expectedLastError.set_port(expectedErrorPort);
        expectedLastError.set_host(expectedErrorHost);

        // Build stats instance for our spout
        final ComponentAggregateStats aggregateStats = buildSpoutAggregateStatsBase();
        aggregateStats.set_last_error(expectedLastError);
        addSpoutStats(expectedSpoutId, aggregateStats);

        // Advance time by 'errorElapsedTimeSecs'
        Time.advanceTimeSecs(errorElapsedTimeSecs);

        // Call method under test.
        final Map<String, Object> result = UIHelpers.getTopologySummary(
            topoPageInfo,
            WINDOW,
            new HashMap<>(),
            "spp"
        );

        // Validate
        assertNotNull(result, "Should never return null");

        // Validate our Spout result
        final Map<String, Object> spoutResult = getSpoutStatsFromTopologySummaryResult(result, expectedSpoutId);
        assertNotNull(spoutResult, "Should have an entry for spout");

        // Verify each piece
        assertEquals(expectedSpoutId, spoutResult.get("spoutId"));
        assertEquals(expectedSpoutId, spoutResult.get("encodedSpoutId"));

        // Verify error
        assertEquals(expectedErrorMsg, spoutResult.get("lastError"));
        assertEquals(expectedErrorPort, spoutResult.get("errorPort"));
        assertEquals(expectedErrorHost, spoutResult.get("errorHost"));
        assertEquals(expectedErrorTime, spoutResult.get("errorTime"));
        assertEquals(expectedErrorElapsedTime, spoutResult.get("errorLapsedSecs"));
    }