class UserEventDispatcher {

    private static final Logger Log = LoggerFactory.getLogger(UserEventDispatcher.class);

    private static List<UserEventListener> listeners =
            new CopyOnWriteArrayList<>();

    private UserEventDispatcher() {
        // Not instantiable.
    }

    /**
     * Registers a listener to receive events.
     *
     * @param listener the listener.
     */
    public static void addListener(UserEventListener listener) {
        if (listener == null) {
            throw new NullPointerException();
        }
        listeners.add(listener);
    }

    /**
     * Unregisters a listener to receive events.
     *
     * @param listener the listener.
     */
    public static void removeListener(UserEventListener listener) {
        listeners.remove(listener);
    }

    /**
     * Dispatches an event to all listeners.
     *
     * @param user the user.
     * @param eventType the event type.
     * @param params event parameters.
     */
    public static void dispatchEvent(User user, EventType eventType, Map<String,Object> params) {<FILL_FUNCTION_BODY>}

    /**
     * Represents valid event types.
     */
    public enum EventType {

        /**
         * A new user was created.
         */
        user_created,

        /**
         * A user is about to be deleted. Note that this event is fired before
         * a user is actually deleted. This allows for referential cleanup
         * before the user is gone.
         */
        user_deleting,

        /**
         * The name, email, password, or extended property of a user was changed.
         */
        user_modified,
    }
}

        for (UserEventListener listener : listeners) {
            try {
                switch (eventType) {
                    case user_created: {
                        listener.userCreated(user, params);
                        break;
                    }
                    case user_deleting: {
                        listener.userDeleting(user, params);
                        break;
                    }
                    case user_modified: {
                        listener.userModified(user, params);
                        break;
                    }
                    default:
                        break;
                }
            }
            catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
        }
    
<no_super_class>