@SuppressWarnings("unchecked")
  @Override
  public SMTPClientFuture<FutureResult<me.normanmaurer.niosmtp.transport.FutureResult.Void>>
      startTLS() {
    if (!isEncrypted()) {
      final SMTPClientFutureImpl<FutureResult<me.normanmaurer.niosmtp.transport.FutureResult.Void>>
          future =
              new SMTPClientFutureImpl<
                  FutureResult<me.normanmaurer.niosmtp.transport.FutureResult.Void>>(false);

      SslHandler sslHandler = new SslHandler(engine, false);
      channel.getPipeline().addFirst(SSL_HANDLER_KEY, sslHandler);
      sslHandler
          .handshake()
          .addListener(
              new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture cfuture) throws Exception {
                  if (cfuture.isSuccess()) {
                    future.setResult(FutureResult.createVoid());
                  } else {
                    future.setResult(FutureResult.create(cfuture.getCause()));
                  }
                }
              });

      return future;
    } else {
      return new ReadySMTPClientFuture<
          FutureResult<me.normanmaurer.niosmtp.transport.FutureResult.Void>>(
          this, FutureResult.create(STARTTLS_EXCEPTION));
    }
  }
 @SuppressWarnings("unchecked")
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
   ctx.getPipeline().remove(this);
   future.setResult(FutureResult.create(e.getCause()));
 }
 @Override
 public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
   closeFuture.setResult(FutureResult.createVoid());
   super.channelClosed(ctx, e);
 }