class PriorityDispatchStrategy extends AbstractDispatcher {

    public void dispatch(Notification notification) {

        // Is this our first attempt at delivering this notification...
        if (notification.getMethod() == null) {
            // ... if so, set initial dispatch method
            NotificationMethod initialMethod = getInitialNotificationMethod(notification.getPriority());
            notification.setMethod(initialMethod);
        }

        // Send the message to the gateway...
        try {
            sendNotification(notification);
        }
        catch (DispatchUnsupportedByUserException | NoSuchProviderException e) {
           logger.error("Failed to dispatch notification: {}:", notification, e);

            // ... if we fail as a result of the custom not being provisioned to accept notifications using the default method,
            // then fall back on the next available dispatch method for this priority
            instrumentFailedDispatch(notification.getMethod(), e);
            fallback(notification, e);
        }
        catch (DispatchException e) {
           logger.error("Failed to dispatch notification: {}:", notification, e);
            // Technical problem delivering the notification;
            instrumentFailedDispatch(notification.getMethod(), e);
            retryProcessor.retry(notification, e);
        }
        catch (RuntimeException e) {
            // Something unexpectedly catastrophic happened; terminal state
            instrumentFailedDispatch(notification.getMethod(), e);
            logger.error("Failed unexpectedly during dispatch of notification {}:", notification, e);
            audit.log(notification, AuditEventState.FAILED, e);
        }
    }

    public  PriorityDispatchStrategy(NotificationAuditor audit, RetryProcessor retryProcessor, RetryManager retryManager, NotificationProviderRegistry providerRegistry);

}