@Override
    public BackgroundException map(final SMBRuntimeException failure) {
        if(failure instanceof SMBApiException) {
            final StringBuilder buffer = new StringBuilder();
            final SMBApiException e = (SMBApiException) failure;
            // NTSTATUS
            final NtStatus status = e.getStatus();
            this.append(buffer, String.format("%s (0x%08x)",
                    LocaleFactory.localizedString(status.name(), "SMB"), e.getStatusCode()));
            switch(status) {
                case STATUS_BAD_NETWORK_NAME:
                case STATUS_NOT_FOUND:
                case STATUS_OBJECT_NAME_NOT_FOUND:
                case STATUS_OBJECT_PATH_NOT_FOUND:
                case STATUS_PATH_NOT_COVERED:
                    return new NotfoundException(buffer.toString(), failure.getCause());
                case STATUS_NOT_IMPLEMENTED:
                case STATUS_NOT_SUPPORTED:
                    return new UnsupportedException(buffer.toString(), failure.getCause());
                case STATUS_ACCESS_DENIED:
                    return new AccessDeniedException(buffer.toString(), failure.getCause());
                case STATUS_OBJECT_NAME_COLLISION:
                    return new ConflictException(buffer.toString(), failure.getCause());
                case STATUS_FILE_LOCK_CONFLICT:
                case STATUS_LOCK_NOT_GRANTED:
                case STATUS_SHARING_VIOLATION:
                    return new LockedException(buffer.toString(), failure.getCause());
                case STATUS_LOGON_FAILURE:
                case STATUS_PASSWORD_EXPIRED:
                case STATUS_ACCOUNT_DISABLED:
                case STATUS_LOGON_TYPE_NOT_GRANTED:
                    return new LoginFailureException(buffer.toString(), failure.getCause());
                case STATUS_DISK_FULL:
                    return new QuotaException(buffer.toString(), failure.getCause());
                case STATUS_IO_TIMEOUT:
                    return new ConnectionTimeoutException(buffer.toString(), failure.getCause());
                case STATUS_CONNECTION_DISCONNECTED:
                case STATUS_CONNECTION_RESET:
                    return new ConnectionRefusedException(buffer.toString(), failure.getCause());
                default:
                    return new InteroperabilityException(buffer.toString(), failure.getCause());
            }
        }
        for(Throwable cause : ExceptionUtils.getThrowableList(failure)) {
            if(cause instanceof TransportException) {
                return new SMBTransportExceptionMappingService().map((TransportException) cause);
            }
            if(cause instanceof TimeoutException) {
                return new ConnectionTimeoutException(cause.getMessage(), cause);
            }
        }
        final Throwable root = ExceptionUtils.getRootCause(failure);
        return new InteroperabilityException(root.getMessage(), failure);
    }
@Test
    public void map() {
        assertEquals("Interoperability failure", new SMBExceptionMappingService().map(new SMBRuntimeException("")).getMessage());
        assertEquals("Please contact your web hosting service provider for assistance.", new SMBExceptionMappingService().map(new SMBRuntimeException("")).getDetail());
        assertEquals("STATUS_OBJECT_NAME_NOT_FOUND (0xc0000034). Please contact your web hosting service provider for assistance.",
                new SMBExceptionMappingService().map(new SMBApiException(3221225524L, SMB2MessageCommandCode.SMB2_CREATE,
                        "Create failed for \\\\localhost\\user\\Dk9I5nTZ", null)).getDetail());
    }