/*
   * Do all the outstanding handshake tasks in the current Thread.
   */
  private SSLEngineResult.HandshakeStatus doTasks() {

    Runnable runnable;

    /*
     * We could run this in a separate thread, but
     * do in the current for now.
     */
    while ((runnable = sslEngine.getDelegatedTask()) != null) {
      runnable.run();
    }
    return sslEngine.getHandshakeStatus();
  }
  /*
   * If the result indicates that we have outstanding tasks to do,
   * go ahead and run them in this thread.
   */
  private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) throws Exception {

    if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
      Runnable runnable;
      while ((runnable = engine.getDelegatedTask()) != null) {
        log("\trunning delegated task...");
        runnable.run();
      }
      HandshakeStatus hsStatus = engine.getHandshakeStatus();
      if (hsStatus == HandshakeStatus.NEED_TASK) {
        throw new Exception("handshake shouldn't need additional tasks");
      }
      log("\tnew HandshakeStatus: " + hsStatus);
    }
  }
  private void checkResult(
      SSLEngine engine,
      SSLEngineResult result,
      HandshakeStatus rqdHsStatus,
      boolean consumed,
      boolean produced)
      throws Exception {

    HandshakeStatus hsStatus = result.getHandshakeStatus();

    if (hsStatus == HandshakeStatus.NEED_TASK) {
      Runnable runnable;
      while ((runnable = engine.getDelegatedTask()) != null) {
        runnable.run();
      }
      hsStatus = engine.getHandshakeStatus();
    }

    if (hsStatus != rqdHsStatus) {
      throw new Exception("Required " + rqdHsStatus + ", got " + hsStatus);
    }

    int bc = result.bytesConsumed();
    int bp = result.bytesProduced();

    if (consumed) {
      if (bc <= 0) {
        throw new Exception("Should have consumed bytes");
      }
    } else {
      if (bc > 0) {
        throw new Exception("Should not have consumed bytes");
      }
    }

    if (produced) {
      if (bp <= 0) {
        throw new Exception("Should have produced bytes");
      }
    } else {
      if (bp > 0) {
        throw new Exception("Should not have produced bytes");
      }
    }
  }
 private ByteBuffer unwrap(ByteBuffer b) throws SSLException {
   in.clear();
   while (b.hasRemaining()) {
     sslEngineResult = sslEngine.unwrap(b, in);
     if (sslEngineResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
       if (DEBUG) {
         log("Handshake NEED TASK");
       }
       Runnable task;
       while ((task = sslEngine.getDelegatedTask()) != null) {
         if (DEBUG) {
           log("Running task: " + task);
         }
         task.run();
       }
     } else if (sslEngineResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED
         || sslEngineResult.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
       return in;
     }
   }
   return in;
 }