private void sendNotification(VerboseEvent event) {
        // form a text component from the check trace
        Component component;
        if (event instanceof PermissionCheckEvent) {
            PermissionCheckEvent permissionEvent = (PermissionCheckEvent) event;
            component = Message.VERBOSE_LOG_PERMISSION.build(
                    permissionEvent.getCheckTarget().describe(),
                    permissionEvent.getPermission(),
                    permissionEvent.getResult().result()
            );
        } else if (event instanceof MetaCheckEvent) {
            MetaCheckEvent metaEvent = (MetaCheckEvent) event;
            component = Message.VERBOSE_LOG_META.build(
                    metaEvent.getCheckTarget().describe(),
                    metaEvent.getKey(),
                    String.valueOf(metaEvent.getResult().result())
            );
        } else {
            throw new IllegalArgumentException("Unknown event type: " + event);
        }

        // just send as a raw message
        if (this.notifiedSender.isConsole()) {
            this.notifiedSender.sendMessage(component);
            return;
        }

        // build the hover text
        List<ComponentLike> hover = new ArrayList<>();

        hover.add(Message.VERBOSE_LOG_HOVER_TYPE.build(event.getType().toString()));
        hover.add(Message.VERBOSE_LOG_HOVER_ORIGIN.build(event.getOrigin().name()));

        Result<?, ?> result = event.getResult();

        if (result instanceof TristateResult) {
            TristateResult tristateResult = (TristateResult) result;

            if (tristateResult.processorClass() != null) {
                hover.add(Message.VERBOSE_LOG_HOVER_PROCESSOR.build(tristateResult.processorClassFriendly()));
            }
        }

        Node node = result.node();
        if (node != null) {
            if (node instanceof MetaNode) {
                hover.add(Message.VERBOSE_LOG_HOVER_CAUSE_META.build((MetaNode) node));
            } else {
                hover.add(Message.VERBOSE_LOG_HOVER_CAUSE.build(node));
            }
        }

        if (event.getCheckQueryOptions().mode() == QueryMode.CONTEXTUAL) {
            hover.add(Message.VERBOSE_LOG_HOVER_CONTEXT.build(event.getCheckQueryOptions().context()));
        }

        hover.add(Message.VERBOSE_LOG_HOVER_THREAD.build(event.getCheckThread()));

        hover.add(Message.VERBOSE_LOG_HOVER_TRACE_TITLE.build());

        Consumer<StackTraceElement> printer = StackTracePrinter.elementToString(str -> hover.add(Message.VERBOSE_LOG_HOVER_TRACE_CONTENT.build(str)));
        int overflow;
        if (shouldFilterStackTrace(event)) {
            overflow = CHAT_FILTERED_PRINTER.process(event.getCheckTrace(), printer);
        } else {
            overflow = CHAT_UNFILTERED_PRINTER.process(event.getCheckTrace(), printer);
        }
        if (overflow != 0) {
            hover.add(Message.VERBOSE_LOG_HOVER_TRACE_OVERFLOW.build(overflow));
        }

        // send the message
        HoverEvent<Component> hoverEvent = HoverEvent.showText(Component.join(JoinConfiguration.newlines(), hover));
        this.notifiedSender.sendMessage(component.hoverEvent(hoverEvent));
    }
Accepts and processes verbose events.

@param event the event to process
common/src/main/java/me/lucko/luckperms/common/verbose/VerboseListener.java