docs: private SSLEngineResult doHandshake(boolean async) throws IOException {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.entry(tc, "doHandshake");
          }
  
          SSLEngineResult sslResult;
          // Line up all the buffers needed for the SSL handshake. Temporary so
          // use indirect allocation for speed.
          int appSize = getConnLink().getAppBufferSize();
          int packetSize = getConnLink().getPacketBufferSize();
          WsByteBuffer localNetBuffer = SSLUtils.allocateByteBuffer(packetSize, true);
          WsByteBuffer decryptedNetBuffer = SSLUtils.allocateByteBuffer(appSize, false);
          WsByteBuffer encryptedAppBuffer = SSLUtils.allocateByteBuffer(packetSize, true);
          // Callback to be used if the request is async.
          MyHandshakeCompletedCallback handshakeCallback = null;
          if (async) {
              handshakeCallback = new MyHandshakeCompletedCallback(this, callback, localNetBuffer, decryptedNetBuffer, encryptedAppBuffer);
          }
  
          try {
              // Do the SSL handshake. Note, if synchronous the handshakeCallback is null.
              sslResult = SSLUtils.handleHandshake(
                                                   getConnLink(),
                                                   localNetBuffer,
                                                   decryptedNetBuffer,
                                                   encryptedAppBuffer,
                                                   null,
                                                   handshakeCallback,
                                                   false);
          } catch (IOException e) {
              // Release buffers used in the handshake.
              localNetBuffer.release();
              localNetBuffer = null;
              decryptedNetBuffer.release();
              decryptedNetBuffer = null;
              encryptedAppBuffer.release();
              encryptedAppBuffer = null;
              throw e;
          }
          if (sslResult != null) {
              // Handshake was done synchronously.
              // Release buffers used in the handshake.
              localNetBuffer.release();
              localNetBuffer = null;
              decryptedNetBuffer.release();
              decryptedNetBuffer = null;
              encryptedAppBuffer.release();
              encryptedAppBuffer = null;
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.exit(tc, "doHandshake");
          }
          return sslResult;
      }