@Override
    public BackgroundException map(final SSLException failure) {
        final StringBuilder buffer = new StringBuilder();
        for(Throwable cause : ExceptionUtils.getThrowableList(failure)) {
            if(cause instanceof SocketException) {
                // Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Broken pipe
                return new DefaultSocketExceptionMappingService().map((SocketException) cause);
            }
        }
        final String message = failure.getMessage();
        for(Alert alert : Alert.values()) {
            if(StringUtils.containsIgnoreCase(message, alert.name())) {
                this.append(buffer, alert.getDescription());
                break;
            }
        }
        if(failure instanceof SSLHandshakeException) {
            if(ExceptionUtils.getRootCause(failure) instanceof CertificateException) {
                log.warn(String.format("Ignore certificate failure %s and drop connection", failure.getMessage()));
                // Server certificate not accepted
                return new ConnectionCanceledException(failure);
            }
            if(ExceptionUtils.getRootCause(failure) instanceof EOFException) {
                // SSL peer shut down incorrectly
                return this.wrap(failure, buffer);
            }
            return new SSLNegotiateException(buffer.toString(), failure);
        }
        if(ExceptionUtils.getRootCause(failure) instanceof GeneralSecurityException) {
            this.append(buffer, ExceptionUtils.getRootCause(failure).getMessage());
            return new InteroperabilityException(buffer.toString(), failure);
        }
        this.append(buffer, message);
        return new InteroperabilityException(buffer.toString(), failure);
    }
@Test
    public void testMap() {
        final BackgroundException f = new SSLExceptionMappingService().map(new SSLException(
                "Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Broken pipe",
                new SSLException("javax.net.ssl.SSLException: java.net.SocketException: Broken pipe",
                        new SocketException("Broken pipe"))));
        assertEquals("Connection failed", f.getMessage());
        assertEquals("Broken pipe. The connection attempt was rejected. The server may be down, or your network may not be properly configured.", f.getDetail());
    }