class MailDelivrer {

    public ExecutionResult deliver(Mail mail) {
        try {
            return tryDeliver(mail);
        } catch (SendFailedException sfe) {
            return handleSenderFailedException(mail, sfe);
        } catch (MessagingException ex) {
            // We check whether this is a 5xx error message, which indicates a permanent failure (like account doesn't exist
            // or mailbox is full or domain is setup wrong). We fail permanently if this was a 5xx error
            boolean isPermanent = new EnhancedMessagingException(ex).isServerError();
            return logAndReturn(mail, ExecutionResult.onFailure(isPermanent, ex));
        } catch (Exception ex) {
            LOGGER.error("Generic exception = permanent failure: {}", ex.getMessage(), ex);
            return logAndReturn(mail, ExecutionResult.permanentFailure(ex));
        }
    }

    public  MailDelivrer(RemoteDeliveryConfiguration configuration, MailDelivrerToHost mailDelivrerToHost, DNSService dnsServer, Bouncer bouncer);
    @VisibleForTesting  MailDelivrer(RemoteDeliveryConfiguration configuration, MailDelivrerToHost mailDelivrerToHost, DnsHelper dnsHelper, Bouncer bouncer);

}