// Path: Web/src/main/java/org/emerjoin/hi/web/ActiveUser.java
// @SessionScoped
// public class ActiveUser implements Serializable {
// 
//     private String uniqueId = null;
//     private String webEventChannel = "default";
//     private List<String> webEventSubscriptions = new ArrayList<>();
//     private String csrfToken = "";
//     private String eventsToken = "";
//     private HashMap<String,Object> data = new HashMap<>();
//     private static final Logger _log = LoggerFactory.getLogger(ActiveUser.class);
//     private static final SecureTokenUtil csrfTokeUtil = new SecureTokenUtil();
// 
//     @Inject
//     private transient Event<UserSubscriptionEvent> channelEvent;
// 
//     @PostConstruct
//     public void init(){
//         this.csrfToken = csrfTokeUtil.makeJwtToken();
//         this.eventsToken = csrfTokeUtil.makeJwtToken();
//         this.uniqueId = UUID.randomUUID().toString();
//     }
// 
//     public void expireTokens(){
//         this.csrfToken = csrfTokeUtil.makeJwtToken();
//         this.eventsToken = csrfTokeUtil.makeJwtToken();
//     }
// 
//     public String getEventsToken() {
//         return eventsToken;
//     }
// 
//     public String getCsrfToken() {
//         return csrfToken;
//     }
// 
//     public HashMap<String, Object> getData() {
//         return data;
//     }
// 
//     public void setData(HashMap<String, Object> data) {
//         this.data = data;
//     }
// 
//     public Object getProperty(String name){
// 
//         return data.get(name);
// 
//     }
// 
//     public Object getProperty(String name,Object defaultValue){
//         Object value = data.get(name);
//         if(value==null)
//             return defaultValue;
//         return value;
//     }
// 
//     public void setProperty(String name, Object value){
// 
//         data.put(name,value);
// 
//     }
// 
//     public List<String> getWebEventSubscriptions() {
//         return Collections.unmodifiableList(
//                 webEventSubscriptions);
//     }
// 
//     public void subscribe(String webEventChannel) {
//         if (webEventChannel == null || webEventChannel.isEmpty())
//             throw new IllegalArgumentException("webEventChannel must not be null nor empty");
//         this.webEventSubscriptions.add(webEventChannel);
//         channelEvent.fire(new JoinChannel(this,
//                 webEventChannel));
//     }
// 
//     public void unsubscribe(String webEventChannel){
//         if(webEventChannel==null||webEventChannel.isEmpty())
//             throw new IllegalArgumentException("webEventChannel must not be null nor empty");
//         if(this.webEventSubscriptions.remove(webEventChannel))
//             channelEvent.fire(new QuitChannel(this,
//                     webEventChannel));
//     }
// 
//     public boolean isSubscribedTo(String webEventChannel){
//         if(webEventChannel==null||webEventChannel.isEmpty())
//             throw new IllegalArgumentException("webEventChannel must not be null nor empty");
//         return this.webEventSubscriptions.contains(
//                 webEventChannel);
//     }
// 
//     public String getWebEventChannel() {
//         return webEventChannel;
//     }
// 
//     public void setWebEventChannel(String webEventChannel) {
//         this.webEventChannel = webEventChannel;
//     }
// 
//     public String getUniqueId() {
//         return uniqueId;
//     }
// }


import org.emerjoin.hi.web.ActiveUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.servlet.AsyncContext;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
            LOGGER.info("No Listeners found for user with Id="+userId);
            return;
        }
        LOGGER.info(String.format("Detaching %d listener(s) from channel",listenerList.size()));
        for(WebEventsListener listener: listenerList){
            consumersPool.remove(listener);
        }
    }

    public void joinChannel(String userId, String channel){
        if(userId==null||userId.isEmpty())
            throw new IllegalArgumentException("userId reference must not be null nor empty");
        if(channel==null||channel.isEmpty())
            throw new IllegalArgumentException("channel reference must not be null nor empty");
        LOGGER.info(String.format("User [%s] joining channel [%s]",userId,channel));
        ListenersPool consumersPool = pools.get(channel);
        if(consumersPool==null){
            consumersPool= new ListenersPool(channel);
            pools.put(channel,consumersPool);
        }
        List<WebEventsListener> listenerList = userListenersMap.get(userId);
        if(listenerList==null||listenerList.isEmpty()){
            LOGGER.info("There are no listeners bound to user with Id="+userId);
            return;
        }else LOGGER.info(String.format("Adding %d listener(s) to channel",listenerList.size()));
        for(WebEventsListener listener: listenerList){
            consumersPool.addListener(listener);
        }
    }

// Path: Web/src/main/java/org/emerjoin/hi/web/ActiveUser.java
// @SessionScoped
// public class ActiveUser implements Serializable {
// 
//     private String uniqueId = null;
//     private String webEventChannel = "default";
//     private List<String> webEventSubscriptions = new ArrayList<>();
//     private String csrfToken = "";
//     private String eventsToken = "";
//     private HashMap<String,Object> data = new HashMap<>();
//     private static final Logger _log = LoggerFactory.getLogger(ActiveUser.class);
//     private static final SecureTokenUtil csrfTokeUtil = new SecureTokenUtil();
// 
//     @Inject
//     private transient Event<UserSubscriptionEvent> channelEvent;
// 
//     @PostConstruct
//     public void init(){
//         this.csrfToken = csrfTokeUtil.makeJwtToken();
//         this.eventsToken = csrfTokeUtil.makeJwtToken();
//         this.uniqueId = UUID.randomUUID().toString();
//     }
// 
//     public void expireTokens(){
//         this.csrfToken = csrfTokeUtil.makeJwtToken();
//         this.eventsToken = csrfTokeUtil.makeJwtToken();
//     }
// 
//     public String getEventsToken() {
//         return eventsToken;
//     }
// 
//     public String getCsrfToken() {
//         return csrfToken;
//     }
// 
//     public HashMap<String, Object> getData() {
//         return data;
//     }
// 
//     public void setData(HashMap<String, Object> data) {
//         this.data = data;
//     }
// 
//     public Object getProperty(String name){
// 
//         return data.get(name);
// 
//     }
// 
//     public Object getProperty(String name,Object defaultValue){
//         Object value = data.get(name);
//         if(value==null)
//             return defaultValue;
//         return value;
//     }
// 
//     public void setProperty(String name, Object value){
// 
//         data.put(name,value);
// 
//     }
// 
//     public List<String> getWebEventSubscriptions() {
//         return Collections.unmodifiableList(
//                 webEventSubscriptions);
//     }
// 
//     public void subscribe(String webEventChannel) {
//         if (webEventChannel == null || webEventChannel.isEmpty())
//             throw new IllegalArgumentException("webEventChannel must not be null nor empty");
//         this.webEventSubscriptions.add(webEventChannel);
//         channelEvent.fire(new JoinChannel(this,
//                 webEventChannel));
//     }
// 
//     public void unsubscribe(String webEventChannel){
//         if(webEventChannel==null||webEventChannel.isEmpty())
//             throw new IllegalArgumentException("webEventChannel must not be null nor empty");
//         if(this.webEventSubscriptions.remove(webEventChannel))
//             channelEvent.fire(new QuitChannel(this,
//                     webEventChannel));
//     }
// 
//     public boolean isSubscribedTo(String webEventChannel){
//         if(webEventChannel==null||webEventChannel.isEmpty())
//             throw new IllegalArgumentException("webEventChannel must not be null nor empty");
//         return this.webEventSubscriptions.contains(
//                 webEventChannel);
//     }
// 
//     public String getWebEventChannel() {
//         return webEventChannel;
//     }
// 
//     public void setWebEventChannel(String webEventChannel) {
//         this.webEventChannel = webEventChannel;
//     }
// 
//     public String getUniqueId() {
//         return uniqueId;
//     }
// }


// Path: Web/src/main/java/org/emerjoin/hi/web/events/sse/WebEventsController.java
import org.emerjoin.hi.web.ActiveUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.servlet.AsyncContext;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

            LOGGER.info("No Listeners found for user with Id="+userId);
            return;
        }
        LOGGER.info(String.format("Detaching %d listener(s) from channel",listenerList.size()));
        for(WebEventsListener listener: listenerList){
            consumersPool.remove(listener);
        }
    }

    public void joinChannel(String userId, String channel){
        if(userId==null||userId.isEmpty())
            throw new IllegalArgumentException("userId reference must not be null nor empty");
        if(channel==null||channel.isEmpty())
            throw new IllegalArgumentException("channel reference must not be null nor empty");
        LOGGER.info(String.format("User [%s] joining channel [%s]",userId,channel));
        ListenersPool consumersPool = pools.get(channel);
        if(consumersPool==null){
            consumersPool= new ListenersPool(channel);
            pools.put(channel,consumersPool);
        }
        List<WebEventsListener> listenerList = userListenersMap.get(userId);
        if(listenerList==null||listenerList.isEmpty()){
            LOGGER.info("There are no listeners bound to user with Id="+userId);
            return;
        }else LOGGER.info(String.format("Adding %d listener(s) to channel",listenerList.size()));
        for(WebEventsListener listener: listenerList){
            consumersPool.addListener(listener);
        }
    }

    WebEventsListener addListener(ActiveUser activeUser, AsyncContext context){