@Nonnull
    @Override
    public String resolveThemeName(@Nonnull final HttpServletRequest request) {
        val context = RequestContextHolder.getRequestContext();
        val serviceContext = WebUtils.getService(context);
        val service = FunctionUtils.doUnchecked(() -> authenticationRequestServiceSelectionStrategies.getObject().resolveService(serviceContext));
        if (service == null) {
            LOGGER.trace("No service is found in the request context. Falling back to the default theme [{}]", getDefaultThemeName());
            return rememberThemeName(request);
        }

        val registeredService = (WebBasedRegisteredService) servicesManager.getObject().findServiceBy(service);
        if (registeredService == null || !registeredService.getAccessStrategy().isServiceAccessAllowed(registeredService, service)) {
            LOGGER.warn("No registered service is found to match [{}] or access is denied. Using default theme [{}]", service, getDefaultThemeName());
            return rememberThemeName(request);
        }
        if (StringUtils.isBlank(registeredService.getTheme())) {
            LOGGER.trace("No theme name is specified for service [{}]. Using default theme [{}]", registeredService, getDefaultThemeName());
            return rememberThemeName(request);
        }

        val themeName = determineThemeNameToChoose(request, service, registeredService);
        return rememberThemeName(request, themeName);
    }
{@link org.springframework.web.servlet.ThemeResolver} to determine the theme for CAS based on the service provided.
The theme resolver will extract the service parameter from the Request object
and attempt to match the URL provided to a Service Id. If the service is
found and there is no theme specified or access to the service is not allowed,
the default theme will be used.
If the service does have a theme associated with it but the theme is a path to a
{@link FileSystemResource} system resource that exists, it will be executed as a
Groovy script that should return the name of the theme.
If the theme value is an HTTP {@link UrlResource}, then the contents referenced by the URL
will be read and the response used as the theme name.
Blank values returned from the script or the URL will result in the default theme being used.
If the theme attribute in the service is not a file or URL resource, it will be evaluated as
a Spring expression and then a search for property files with the theme name as the base name
is done using configured template prefix locations.
If nothing is found in template prefix locations, the {@link java.util.ResourceBundle#getBundle(String, Locale)} method
using the locale of the request is used to look for the theme properties to ensure it exists.
If theme properties don't exist for the specified theme name then the default theme will be used.

@author Scott Battaglia
@since 3.0.0
support/cas-server-support-themes-core/src/main/java/org/apereo/cas/services/web/RegisteredServiceThemeResolver.java