class GroupEventDispatcher {

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

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

    private GroupEventDispatcher() {
        // Not instantiable.
    }

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

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

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

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

        /**
         * A new group was created.
         */
        group_created,

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

        /**
         * The name, description, or extended property of a group was changed.
         */
        group_modified,

        /**
         * A member was added to a group.
         */
        member_added,

        /**
         * A member was removed from a group.
         */
        member_removed,

        /**
         * An administrator was added to a group.
         */
        admin_added,

        /**
         * An administrator was removed from a group.
         */
        admin_removed;
    }
}

        for (GroupEventListener listener : listeners) {
            try {
                switch (eventType) {
                    case group_created: {
                        listener.groupCreated(group, params);
                        break;
                    }
                    case group_deleting: {
                        listener.groupDeleting(group, params);
                        break;
                    }
                    case member_added: {
                        listener.memberAdded(group, params);
                        break;
                    }
                    case member_removed: {
                        listener.memberRemoved(group, params);
                        break;
                    }
                    case admin_added: {
                        listener.adminAdded(group, params);
                        break;
                    }
                    case admin_removed: {
                        listener.adminRemoved(group, params);
                        break;
                    }
                    case group_modified: {
                        listener.groupModified(group, params);
                        break;
                    }
                    default:
                        break;
                }
            }
            catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
        }
    
<no_super_class>