docs: private void readyOutbound(VirtualConnection inVC, boolean async) throws IOException {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.entry(tc, "readyOutbound, vc=" + getVCHash());
          }
  
          final SSLChannelData config = this.sslChannel.getConfig();
          // Encrypted buffer from the network.
          WsByteBuffer netBuffer = SSLUtils.allocateByteBuffer(getPacketBufferSize(), config.getEncryptBuffersDirect());
          // Unencrypted buffer from the ssl engine output to be handed up to the application.
          WsByteBuffer decryptedNetBuffer = SSLUtils.allocateByteBuffer(getAppBufferSize(), config.getDecryptBuffersDirect());
          // Encrypted buffer from the ssl engine to be sent sent out on the network.
          WsByteBuffer encryptedAppBuffer = SSLUtils.allocateByteBuffer(getPacketBufferSize(), true);
          // Result from the SSL engine.
          SSLEngineResult sslResult = null;
          // Build the required callback.
          MyHandshakeCompletedCallback callback = null;
          // Flag if an error took place
          IOException exception = null;
  
          // Only create the callback if this is for an async request.
          if (async) {
              callback = new MyHandshakeCompletedCallback(this, netBuffer, decryptedNetBuffer, encryptedAppBuffer, FlowType.OUTBOUND);
          }
  
          try {
              // Start the aynchronous SSL handshake.
              sslResult = SSLUtils.handleHandshake(this, netBuffer, decryptedNetBuffer,
                                                   encryptedAppBuffer, sslResult, callback, false);
              // Check to see if the work was able to be done synchronously.
              if (sslResult != null) {
                  // Handshake was done synchronously.
                  readyOutboundPostHandshake(netBuffer, decryptedNetBuffer,
                                             encryptedAppBuffer, sslResult.getHandshakeStatus(), async);
              }
          } catch (IOException e) {
              exception = e;
          } catch (ReadOnlyBufferException e) {
              exception = new IOException("Caught exception: " + e);
          }
  
          if (exception != null) {
              FFDCFilter.processException(exception, getClass().getName(), "540", this);
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  Tr.debug(tc, "Caught exception during handshake after connect, " + exception);
              }
              // Release the buffers.
              if (netBuffer != null) {
                  netBuffer.release();
                  netBuffer = null;
                  getDeviceReadInterface().setBuffers(null);
              }
              if (decryptedNetBuffer != null) {
                  decryptedNetBuffer.release();
                  decryptedNetBuffer = null;
              }
              if (encryptedAppBuffer != null) {
                  encryptedAppBuffer.release();
                  encryptedAppBuffer = null;
              }
              if (async) {
                  close(inVC, exception);
              } else {
                  this.syncConnectFailure = true;
                  close(inVC, exception);
                  throw exception;
              }
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.exit(tc, "readyOutbound");
          }
          return;
      }