@Override
    public BackgroundException map(final IOException e) {
        if(ExceptionUtils.getRootCause(e) != e && ExceptionUtils.getRootCause(e) instanceof SSHException) {
            return this.map((SSHException) ExceptionUtils.getRootCause(e));
        }
        final StringBuilder buffer = new StringBuilder();
        this.append(buffer, e.getMessage());
        if(ExceptionUtils.getRootCause(e) != e) {
            if(!StringUtils.equals(e.getMessage(), ExceptionUtils.getRootCause(e).getMessage())) {
                this.append(buffer, ExceptionUtils.getRootCause(e).getMessage());
            }
        }
        if(e instanceof SFTPException) {
            final SFTPException failure = (SFTPException) e;
            final Response.StatusCode code = failure.getStatusCode();
            switch(code) {
                case FILE_ALREADY_EXISTS:
                    return new ConflictException(buffer.toString(),e);
                case NO_SUCH_FILE:
                case NO_SUCH_PATH:
                case INVALID_HANDLE:
                    return new NotfoundException(buffer.toString(), e);
                case PERMISSION_DENIED:
                case WRITE_PROTECT:
                case CANNOT_DELETE:
                    return new AccessDeniedException(buffer.toString(), e);
                case NO_CONNECTION:
                case CONNECITON_LOST:
                    return new ConnectionRefusedException(buffer.toString(), e);
                case NO_MEDIA:
                    break;
                case NO_SPACE_ON_FILESYSTEM:
                case QUOTA_EXCEEDED:
                    return new QuotaException(buffer.toString(), e);
                case LOCK_CONFLICT:
                    return new LockedException(buffer.toString(), e);
                default:
                    return new InteroperabilityException(buffer.toString(), e);
            }
        }
        if(e instanceof UserAuthException) {
            return new LoginFailureException(buffer.toString(), e);
        }
        if(e instanceof ConnectionException) {
            return new ConnectionRefusedException(buffer.toString(), e);
        }
        if(e instanceof Buffer.BufferException) {
            return new InteroperabilityException(buffer.toString(), e);
        }
        if(e instanceof SSHException) {
            final SSHException failure = (SSHException) e;
            final DisconnectReason reason = failure.getDisconnectReason();
            return this.map(e, buffer, reason);
        }
        return this.wrap(e, buffer);
    }
@Test
    public void testWrapped() {
        assertEquals(InteroperabilityException.class,
            new SFTPExceptionMappingService().map(new TransportException(DisconnectReason.UNKNOWN, new SSHException(DisconnectReason.PROTOCOL_ERROR))).getClass());
    }