// Path: src/main/java/org/pdfsam/eventstudio/util/RequireUtils.java
// public static void requireNotNull(Object victim) {
//     if (victim == null) {
//         throw new IllegalArgumentException("The input object cannot be null");
//     }
// }
// 
// Path: src/main/java/org/pdfsam/eventstudio/Annotations.java
// static class ReflectiveListenerDescriptor {
// 
//     private final EventListener listenerAnnotation;
//     private final Method method;
// 
//     public ReflectiveListenerDescriptor(EventListener listenerAnnotation, Method method) {
//         this.listenerAnnotation = listenerAnnotation;
//         this.method = method;
//     }
// 
//     public EventListener getListenerAnnotation() {
//         return listenerAnnotation;
//     }
// 
//     public Method getMethod() {
//         return method;
//     }
// }
// 
// Path: src/main/java/org/pdfsam/eventstudio/exception/BroadcastInterruptionException.java
// public class BroadcastInterruptionException extends EventStudioException {
// 
//     public BroadcastInterruptionException(String message) {
//         super(message);
//     }
// 
// }
// 
// Path: src/main/java/org/pdfsam/eventstudio/exception/EventStudioException.java
// public class EventStudioException extends RuntimeException {
// 
//     public EventStudioException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public EventStudioException(String message) {
//         super(message);
//     }
// 
//     public EventStudioException(Throwable cause) {
//         super(cause);
//     }
// 
// }


import org.pdfsam.eventstudio.Annotations.ReflectiveListenerDescriptor;
import org.pdfsam.eventstudio.exception.BroadcastInterruptionException;
import org.pdfsam.eventstudio.exception.EventStudioException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.pdfsam.eventstudio.util.RequireUtils.requireNotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantReadWriteLock;
        TreeSet<ListenerReferenceHolder> set = listeners.get(eventClass);
        if (set != null) {
            lock.readLock().unlock();
            lock.writeLock().lock();
            try {
                return removeListenerAndSetIfNeeded(eventClass, listener, set);
            } finally {
                lock.writeLock().unlock();
            }
        }
        lock.readLock().unlock();
        return false;
    }

    private boolean removeListenerAndSetIfNeeded(Class<?> eventClass, ListenerReferenceHolder listener,
            TreeSet<ListenerReferenceHolder> set) {
        if (set.remove(listener)) {
            if (set.isEmpty()) {
                listeners.remove(eventClass);
                LOG.trace("Removed empty listeners set for {}", eventClass);
            }
            return true;
        }
        return false;
    }

    /**
     * @return A sorted set containing the listeners queue for the given class.
     */
    List<ListenerReferenceHolder> nullSafeGetListeners(Class<?> eventClass) {
// Path: src/main/java/org/pdfsam/eventstudio/util/RequireUtils.java
// public static void requireNotNull(Object victim) {
//     if (victim == null) {
//         throw new IllegalArgumentException("The input object cannot be null");
//     }
// }
// 
// Path: src/main/java/org/pdfsam/eventstudio/Annotations.java
// static class ReflectiveListenerDescriptor {
// 
//     private final EventListener listenerAnnotation;
//     private final Method method;
// 
//     public ReflectiveListenerDescriptor(EventListener listenerAnnotation, Method method) {
//         this.listenerAnnotation = listenerAnnotation;
//         this.method = method;
//     }
// 
//     public EventListener getListenerAnnotation() {
//         return listenerAnnotation;
//     }
// 
//     public Method getMethod() {
//         return method;
//     }
// }
// 
// Path: src/main/java/org/pdfsam/eventstudio/exception/BroadcastInterruptionException.java
// public class BroadcastInterruptionException extends EventStudioException {
// 
//     public BroadcastInterruptionException(String message) {
//         super(message);
//     }
// 
// }
// 
// Path: src/main/java/org/pdfsam/eventstudio/exception/EventStudioException.java
// public class EventStudioException extends RuntimeException {
// 
//     public EventStudioException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public EventStudioException(String message) {
//         super(message);
//     }
// 
//     public EventStudioException(Throwable cause) {
//         super(cause);
//     }
// 
// }


// Path: src/main/java/org/pdfsam/eventstudio/Listeners.java
import org.pdfsam.eventstudio.Annotations.ReflectiveListenerDescriptor;
import org.pdfsam.eventstudio.exception.BroadcastInterruptionException;
import org.pdfsam.eventstudio.exception.EventStudioException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.pdfsam.eventstudio.util.RequireUtils.requireNotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantReadWriteLock;

        TreeSet<ListenerReferenceHolder> set = listeners.get(eventClass);
        if (set != null) {
            lock.readLock().unlock();
            lock.writeLock().lock();
            try {
                return removeListenerAndSetIfNeeded(eventClass, listener, set);
            } finally {
                lock.writeLock().unlock();
            }
        }
        lock.readLock().unlock();
        return false;
    }

    private boolean removeListenerAndSetIfNeeded(Class<?> eventClass, ListenerReferenceHolder listener,
            TreeSet<ListenerReferenceHolder> set) {
        if (set.remove(listener)) {
            if (set.isEmpty()) {
                listeners.remove(eventClass);
                LOG.trace("Removed empty listeners set for {}", eventClass);
            }
            return true;
        }
        return false;
    }

    /**
     * @return A sorted set containing the listeners queue for the given class.
     */
    List<ListenerReferenceHolder> nullSafeGetListeners(Class<?> eventClass) {
        requireNotNull(eventClass);