docs: private void writeSocket1(@NotNull WireOut outWire, @Nullable SocketChannel clientChannel) throws
              IOException {
  
          if (LOG.isDebugEnabled())
              Jvm.debug().on(getClass(), "sending :" + Wires.fromSizePrefixedBlobs((Wire) outWire));
  
          if (clientChannel == null) {
              LOG.info("Connection Dropped");
              throw new ConnectionDroppedException("Connection Dropped");
          }
  
          assert outBytesLock.isHeldByCurrentThread();
  
          long start = Time.currentTimeMillis();
          assert outWire.startUse();
          try {
              @NotNull final Bytes<?> bytes = outWire.bytes();
              @Nullable final ByteBuffer outBuffer = (ByteBuffer) bytes.underlyingObject();
              outBuffer.limit((int) bytes.writePosition());
              outBuffer.position(0);
  
              // this check ensure that a put does not occur while currently re-subscribing
              assert outBytesLock().isHeldByCurrentThread();
  
              boolean isOutBufferFull = false;
              logToStandardOutMessageSent(outWire, outBuffer);
              updateLargestChunkSoFarSize(outBuffer);
  
              try {
  
                  int prevRemaining = outBuffer.remaining();
                  while (outBuffer.remaining() > 0) {
  
                      // if the socket was changed, we need to resend using this one instead
                      // unless the client channel still has not be set, then we will use this one
                      // this can happen during the handshaking phase of a new connection
  
                      if (clientChannel != this.clientChannel)
                          throw new ConnectionDroppedException("Connection has Changed");
  
                      int len = clientChannel.write(outBuffer);
                      if (len == -1)
                          throw new IORuntimeException("Disconnection to server=" +
                                  socketAddressSupplier + ", name=" + name);
  
                      if (LOG.isDebugEnabled())
                          Jvm.debug().on(getClass(), "W:" + len + ",socket=" + socketAddressSupplier.get());
  
                      // reset the timer if we wrote something.
                      if (prevRemaining != outBuffer.remaining()) {
                          start = Time.currentTimeMillis();
                          isOutBufferFull = false;
                          //  if (Jvm.isDebug() && outBuffer.remaining() == 0)
                          //    System.out.println("W: " + (prevRemaining - outBuffer
                          //          .remaining()));
                          prevRemaining = outBuffer.remaining();
                          @NotNull final TcpSocketConsumer tcpSocketConsumer = this.tcpSocketConsumer;
  
                          if (tcpSocketConsumer != null)
                              this.tcpSocketConsumer.lastTimeMessageReceivedOrSent = start;
                      } else {
                          if (!isOutBufferFull && Jvm.isDebug() && LOG.isDebugEnabled())
                              Jvm.debug().on(getClass(), "----> TCP write buffer is FULL! " + outBuffer.remaining() + " bytes" +
                                      " remaining.");
                          isOutBufferFull = true;
  
                          long writeTime = Time.currentTimeMillis() - start;
  
                          // the reason that this is so large is that results from a bootstrap can
                          // take a very long time to send all the data from the server to the client
                          // we don't want this to fail as it will cause a disconnection !
                          if (writeTime > TimeUnit.MINUTES.toMillis(15)) {
  
                              for (@NotNull Map.Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet()) {
                                  Thread thread = entry.getKey();
                                  if (thread.getThreadGroup().getName().equals("system"))
                                      continue;
                                  @NotNull StringBuilder sb = new StringBuilder();
                                  sb.append("\n========= THREAD DUMP =========\n");
                                  sb.append(thread).append(" ").append(thread.getState());
                                  Jvm.trimStackTrace(sb, entry.getValue());
                                  sb.append("\n");
                                  Jvm.warn().on(getClass(), sb.toString());
                              }
  
                              closeSocket();
  
                              throw new IORuntimeException("Took " + writeTime + " ms " +
                                      "to perform a write, remaining= " + outBuffer.remaining());
                          }
  
                          // its important to yield, if the read buffer gets full
                          // we wont be able to write, lets give some time to the read thread !
                          Thread.yield();
                      }
                  }
              } catch (IOException e) {
                  closeSocket();
                  throw e;
              }
  
              outBuffer.clear();
              bytes.clear();
          } finally {
              assert outWire.endUse();
          }
      }