class OSSOHeaderDecoder implements IUserDecoder {

    private static final Logger LOGGER = Logger.getLogger(OSSOHeaderDecoder.class.getName());

    protected static final String OSSO_COOKIE_TIMESTAMP_HEADER = "osso-cookie-timestamp";
    protected static final String OSSO_TIMEOUT_EXCEEDED_HEADER = "osso-idle-timeout-exceeded";
    protected static final String OSSO_SUBSCRIBER_DN_HEADER = "osso-subscriber-dn";
    protected static final String OSSO_SUBSCRIBER_HEADER = "osso-subscriber";
    protected static final String OSSO_USER_DN_HEADER = "osso-user-dn";
    protected static final String OSSO_USER_GUID_HEADER = "osso-user-guid";

    @Override
    public User fromRequest(HttpServletRequest request) {<FILL_FUNCTION_BODY>}
}

        Date cookieTimestamp = null;

        // Avoid classification as a taint bug.
        var username = Laundromat.launderInput(request.getHeader(OSSO_USER_DN_HEADER));
        var timeouted = Laundromat.launderInput(request.getHeader(OSSO_TIMEOUT_EXCEEDED_HEADER));
        var timestamp = Laundromat.launderInput(request.getHeader(OSSO_COOKIE_TIMESTAMP_HEADER));
        var userguid = Laundromat.launderInput(request.getHeader(OSSO_USER_GUID_HEADER));

        if (username == null || username.isEmpty()) {
            LOGGER.log(Level.WARNING,
                    "Can not construct an user: username could not be extracted from headers: {0}",
                    String.join(",", Collections.list(request.getHeaderNames())));
            return null;
        }

        if (userguid == null || userguid.isEmpty()) {
            LOGGER.log(Level.WARNING,
                    "Can not construct an user: userguid could not be extracted from headers: {0}",
                    String.join(",", Collections.list(request.getHeaderNames())));
            return null;
        }

        /*
          The timestamp cookie can be corrupted.
         */
        try {
            cookieTimestamp = Timestamp.decodeTimeCookie(timestamp);
        } catch (NumberFormatException ex) {
            LOGGER.log(Level.WARNING,
                    String.format("Unparseable timestamp cookie \"%s\" for user \"%s\"",
                            timestamp, username), ex);
        }

        /*
          Creating new user entity with provided information. The entity can be
          checked if the timeout expired via {@link User#isTimeouted()}.
         */
        User user = new User(username, userguid, cookieTimestamp,
                "true".equalsIgnoreCase(timeouted));

        user.setAttribute("subscriber-dn", request.getHeader(OSSO_SUBSCRIBER_DN_HEADER));
        user.setAttribute("subscriber", request.getHeader(OSSO_SUBSCRIBER_HEADER));

        if (user.isTimeouted()) {
            LOGGER.log(Level.WARNING, "Can not construct an user \"{0}\": header is timeouted",
                    username);
            return null;
        }

        return user;
    
<no_super_class>