class DefaultLogoutLogic extends AbstractExceptionAwareLogic implements LogoutLogic {

    /** Constant <code>INSTANCE</code> */
    public static final LogoutLogic INSTANCE = new DefaultLogoutLogic();

    /** {@inheritDoc} */
    @Override
    public Object perform(final Config config, final String defaultUrl, final String inputLogoutUrlPattern, final Boolean inputLocalLogout,
                          final Boolean inputDestroySession, final Boolean inputCentralLogout, final FrameworkParameters parameters) {<FILL_FUNCTION_BODY>}

    /**
     * <p>enhanceRedirectUrl.</p>
     *
     * @param ctx a {@link CallContext} object
     * @param config a {@link Config} object
     * @param client a {@link Client} object
     * @param redirectUrl a {@link String} object
     * @return a {@link String} object
     */
    protected String enhanceRedirectUrl(final CallContext ctx, final Config config, final Client client, final String redirectUrl) {
        return redirectUrl;
    }
}


        LOGGER.debug("=== LOGOUT ===");

        // checks
        val ctx = buildContext(config, parameters);
        val webContext = ctx.webContext();
        val httpActionAdapter = config.getHttpActionAdapter();
        assertNotNull("httpActionAdapter", httpActionAdapter);

        HttpAction action;
        try {
            val sessionStore = ctx.sessionStore();

            // default values
            final String logoutUrlPattern;
            logoutUrlPattern = Objects.requireNonNullElse(inputLogoutUrlPattern, Pac4jConstants.DEFAULT_LOGOUT_URL_PATTERN_VALUE);
            val localLogout = inputLocalLogout == null || inputLocalLogout;
            val destroySession = inputDestroySession != null && inputDestroySession;
            val centralLogout = inputCentralLogout != null && inputCentralLogout;

            assertNotBlank(Pac4jConstants.LOGOUT_URL_PATTERN, logoutUrlPattern);
            val configClients = config.getClients();
            assertNotNull("configClients", configClients);

            // logic
            val manager = ctx.profileManagerFactory().apply(webContext, sessionStore);
            manager.setConfig(config);
            val profiles = manager.getProfiles();

            // compute redirection URL
            val url = webContext.getRequestParameter(Pac4jConstants.URL);
            var redirectUrl = defaultUrl;
            if (url.isPresent() && Pattern.matches(logoutUrlPattern, url.get())) {
                redirectUrl = url.get();
            }
            LOGGER.debug("redirectUrl: {}", redirectUrl);
            if (redirectUrl != null) {
                action = HttpActionHelper.buildRedirectUrlAction(webContext, redirectUrl);
            } else {
                action = NoContentAction.INSTANCE;
            }

            // local logout if requested or multiple profiles
            if (localLogout || profiles.size() > 1) {
                LOGGER.debug("Performing application logout");
                manager.removeProfiles();
                String sessionId = null;
                if (sessionStore != null) {
                    sessionId = sessionStore.getSessionId(webContext, false).orElse(null);
                    if (destroySession) {
                        val removed = sessionStore.destroySession(webContext);
                        if (!removed) {
                            LOGGER.error("Unable to destroy the web session. The session store may not support this feature");
                        }
                    }
                } else {
                    LOGGER.error("No session store available for this web context");
                }
                val sessionLogoutHandler = config.getSessionLogoutHandler();
                if (sessionLogoutHandler != null && sessionId != null) {
                    sessionLogoutHandler.cleanRecord(sessionId);
                }
            }

            // central logout
            if (centralLogout) {
                LOGGER.debug("Performing central logout");
                for (val profile : profiles) {
                    LOGGER.debug("Profile: {}", profile);
                    val clientName = profile.getClientName();
                    if (clientName != null) {
                        val client = configClients.findClient(clientName);
                        if (client.isPresent()) {
                            String targetUrl = null;
                            if (redirectUrl != null) {
                                redirectUrl = enhanceRedirectUrl(ctx, config, client.get(), redirectUrl);
                                if (redirectUrl.startsWith(HttpConstants.SCHEME_HTTP) ||
                                    redirectUrl.startsWith(HttpConstants.SCHEME_HTTPS)) {
                                    targetUrl = redirectUrl;
                                }
                            }
                            val logoutAction =
                                client.get().getLogoutAction(ctx, profile, targetUrl);
                            LOGGER.debug("Logout action: {}", logoutAction);
                            if (logoutAction.isPresent()) {
                                action = logoutAction.get();
                                break;
                            }
                        }
                    }
                }
            }

        } catch (final RuntimeException e) {
            return handleException(e, httpActionAdapter, webContext);
        }

        return httpActionAdapter.adapt(action, webContext);
    
<methods>public non-sealed void <init>() <variables>private java.lang.String errorUrl