private static Map<String, List<String>> getHeaders(HttpServletRequest request) {

        @SuppressWarnings("unchecked") // getHeaderNames() is explicitly documented as returning a Enumeration<String>
        Enumeration<String> names = (Enumeration<String>) request.getHeaderNames();

        // Represent the total lack of headers as an empty map, not null
        if (names == null)
            return Collections.emptyMap();

        // Headers are case-insensitive
        Map<String, List<String>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        while (names.hasMoreElements()) {

            String name = names.nextElement();

            @SuppressWarnings("unchecked") // getHeaders() is explicitly documented as returning a Enumeration<String>
            Enumeration<String> values = (Enumeration<String>) request.getHeaders(name);
            if (values != null && values.hasMoreElements())
                headers.put(name, Collections.unmodifiableList(Collections.list(values)));

        }

        return Collections.unmodifiableMap(headers);

    }
Returns an unmodifiable Map of all HTTP headers within the given request.
If there are no such headers, the returned Map will be empty. As there
may be many values for each header, each value is stored as a separate
entry in an unmodifiable List. The keys of the returned map (header
names) are case-insensitive.

@param request
    The HTTP request to extract all headers from.

@return
    An unmodifiable Map of all HTTP headers in the given request.
guacamole-ext/src/main/java/org/apache/guacamole/net/RequestDetails.java