code: @Override
      public ChannelFuture connect(final SocketAddress remoteAddress)
      {
          if (!(remoteAddress instanceof InetSocketAddress)) {
              throw new IllegalArgumentException("expecting InetSocketAddress");
          }
          final SettableChannelFuture settableChannelFuture = new SettableChannelFuture();
          super.connect(socksProxyAddr).addListener(new ChannelFutureListener()
          {
              @Override
              public void operationComplete(ChannelFuture future)
                      throws Exception
              {
                  settableChannelFuture.setChannel(future.getChannel());
                  if (future.isSuccess()) {
                      socksConnect(future.getChannel(), (InetSocketAddress) remoteAddress).addListener(new ChannelFutureListener()
                      {
                          @Override
                          public void operationComplete(ChannelFuture innerFuture)
                                  throws Exception
                          {
                              if (innerFuture.isSuccess()) {
                                  settableChannelFuture.setSuccess();
                              }
                              else {
                                  settableChannelFuture.setFailure(innerFuture.getCause());
                              }
                          }
                      });
                  }
                  else {
                      settableChannelFuture.setFailure(future.getCause());
                  }
              }
          });
          return settableChannelFuture;
      }
docs: Hijack the connect method to connect to socks proxy and then
  send the connection handshake once connection to proxy is established.
  
  @return returns a ChannelFuture, it will be ready once the connection to
  socks and the remote address is established ( i.e. after the handshake completes )