// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestUserProfile.java
// public class RequestUserProfile {
// 
//     private final RequestPac4JSecurityContext context;
// 
//     public RequestUserProfile(RequestPac4JSecurityContext context) {
//         this.context = context;
//     }
// 
//     public Optional<UserProfile> profile() {
//         return context.context()
//                 .flatMap(Pac4JSecurityContext::getProfiles)
//                 .flatMap(ps -> ProfileHelper.flatIntoOneProfile(ps));
//     }
// }
// 
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestJaxRsContext.java
// public class RequestJaxRsContext {
// 
//     private final ProvidersContext providers;
//     private final ContainerRequestContext context;
// 
//     public RequestJaxRsContext(Providers providers, ContainerRequestContext context) {
//         this.providers = new ProvidersContext(providers);
//         this.context = context;
//     }
// 
//     public Optional<JaxRsContext> context() {
//         return new RequestPac4JSecurityContext(context).context().map(Pac4JSecurityContext::getContext);
//     }
// 
//     public JaxRsContext contextOrNew() {
//         return context().orElse(providers.resolveNotNull(JaxRsContextFactory.class).provides(context));
//     }
// }
// 
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestPac4JSecurityContext.java
// public class RequestPac4JSecurityContext {
// 
//     private final SecurityContext securityContext;
// 
//     public RequestPac4JSecurityContext(JaxRsContext context) {
//         this(context.getRequestContext());
//     }
// 
//     public RequestPac4JSecurityContext(ContainerRequestContext request) {
//         this(request.getSecurityContext());
//     }
// 
//     public RequestPac4JSecurityContext(SecurityContext securityContext) {
//         this.securityContext = securityContext;
//     }
// 
//     public Optional<Pac4JSecurityContext> context() {
//         if (securityContext instanceof Pac4JSecurityContext) {
//             return Optional.of((Pac4JSecurityContext) securityContext);
//         } else {
//             return Optional.empty();
//         }
//     }
// }
// 
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestProfileManager.java
// public class RequestProfileManager {
// 
//     private final RequestJaxRsContext context;
// 
//     public RequestProfileManager(RequestJaxRsContext context) {
//         this.context = context;
//     }
// 
//     public JaxRsProfileManager profileManager() {
//         return new JaxRsProfileManager(context.contextOrNew());
//     }
// }


import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.InjectionResolver;
import org.glassfish.jersey.internal.util.ReflectionHelper;
import org.glassfish.jersey.internal.util.collection.ClassTypePair;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.internal.inject.AbstractValueParamProvider;
import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider;
import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver;
import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.spi.internal.ValueParamProvider;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.ProfileManager;
import org.pac4j.core.profile.UserProfile;
import org.pac4j.jax.rs.annotations.Pac4JProfile;
import org.pac4j.jax.rs.annotations.Pac4JProfileManager;
import org.pac4j.jax.rs.helpers.RequestUserProfile;
import org.pac4j.jax.rs.helpers.RequestJaxRsContext;
import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext;
import org.pac4j.jax.rs.helpers.RequestProfileManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.ext.Providers;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
        ProfileManagerValueFactory(Providers providers) {
            this.providers = providers;
        }

        @Override
        public ProfileManager<CommonProfile> apply(ContainerRequest containerRequest) {
            return new RequestProfileManager(new RequestJaxRsContext(providers, containerRequest))
                .profileManager();
        }
    }

    static class ProfileValueFactory implements ProfileFactory {
        @Override
        public UserProfile apply(ContainerRequest containerRequest) {
            return optionalProfile(containerRequest)
                .orElseThrow(() -> {
                    LOG.debug("Cannot inject a Pac4j profile into an unauthenticated request, responding with 401");
                    return new WebApplicationException(401);
                });
        }
    }

    static class OptionalProfileValueFactory implements OptionalProfileFactory {
        @Override
        public Optional<UserProfile> apply(ContainerRequest containerRequest) {
            return optionalProfile(containerRequest);
        }
    }

    private static Optional<UserProfile> optionalProfile(ContainerRequest containerRequest) {
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestUserProfile.java
// public class RequestUserProfile {
// 
//     private final RequestPac4JSecurityContext context;
// 
//     public RequestUserProfile(RequestPac4JSecurityContext context) {
//         this.context = context;
//     }
// 
//     public Optional<UserProfile> profile() {
//         return context.context()
//                 .flatMap(Pac4JSecurityContext::getProfiles)
//                 .flatMap(ps -> ProfileHelper.flatIntoOneProfile(ps));
//     }
// }
// 
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestJaxRsContext.java
// public class RequestJaxRsContext {
// 
//     private final ProvidersContext providers;
//     private final ContainerRequestContext context;
// 
//     public RequestJaxRsContext(Providers providers, ContainerRequestContext context) {
//         this.providers = new ProvidersContext(providers);
//         this.context = context;
//     }
// 
//     public Optional<JaxRsContext> context() {
//         return new RequestPac4JSecurityContext(context).context().map(Pac4JSecurityContext::getContext);
//     }
// 
//     public JaxRsContext contextOrNew() {
//         return context().orElse(providers.resolveNotNull(JaxRsContextFactory.class).provides(context));
//     }
// }
// 
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestPac4JSecurityContext.java
// public class RequestPac4JSecurityContext {
// 
//     private final SecurityContext securityContext;
// 
//     public RequestPac4JSecurityContext(JaxRsContext context) {
//         this(context.getRequestContext());
//     }
// 
//     public RequestPac4JSecurityContext(ContainerRequestContext request) {
//         this(request.getSecurityContext());
//     }
// 
//     public RequestPac4JSecurityContext(SecurityContext securityContext) {
//         this.securityContext = securityContext;
//     }
// 
//     public Optional<Pac4JSecurityContext> context() {
//         if (securityContext instanceof Pac4JSecurityContext) {
//             return Optional.of((Pac4JSecurityContext) securityContext);
//         } else {
//             return Optional.empty();
//         }
//     }
// }
// 
// Path: core/src/main/java/org/pac4j/jax/rs/helpers/RequestProfileManager.java
// public class RequestProfileManager {
// 
//     private final RequestJaxRsContext context;
// 
//     public RequestProfileManager(RequestJaxRsContext context) {
//         this.context = context;
//     }
// 
//     public JaxRsProfileManager profileManager() {
//         return new JaxRsProfileManager(context.contextOrNew());
//     }
// }


// Path: jersey/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.InjectionResolver;
import org.glassfish.jersey.internal.util.ReflectionHelper;
import org.glassfish.jersey.internal.util.collection.ClassTypePair;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.internal.inject.AbstractValueParamProvider;
import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider;
import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver;
import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.spi.internal.ValueParamProvider;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.ProfileManager;
import org.pac4j.core.profile.UserProfile;
import org.pac4j.jax.rs.annotations.Pac4JProfile;
import org.pac4j.jax.rs.annotations.Pac4JProfileManager;
import org.pac4j.jax.rs.helpers.RequestUserProfile;
import org.pac4j.jax.rs.helpers.RequestJaxRsContext;
import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext;
import org.pac4j.jax.rs.helpers.RequestProfileManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.ext.Providers;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

        ProfileManagerValueFactory(Providers providers) {
            this.providers = providers;
        }

        @Override
        public ProfileManager<CommonProfile> apply(ContainerRequest containerRequest) {
            return new RequestProfileManager(new RequestJaxRsContext(providers, containerRequest))
                .profileManager();
        }
    }

    static class ProfileValueFactory implements ProfileFactory {
        @Override
        public UserProfile apply(ContainerRequest containerRequest) {
            return optionalProfile(containerRequest)
                .orElseThrow(() -> {
                    LOG.debug("Cannot inject a Pac4j profile into an unauthenticated request, responding with 401");
                    return new WebApplicationException(401);
                });
        }
    }

    static class OptionalProfileValueFactory implements OptionalProfileFactory {
        @Override
        public Optional<UserProfile> apply(ContainerRequest containerRequest) {
            return optionalProfile(containerRequest);
        }
    }

    private static Optional<UserProfile> optionalProfile(ContainerRequest containerRequest) {
        RequestPac4JSecurityContext securityContext = new RequestPac4JSecurityContext(containerRequest);