src/main/java/com/hibegin/http/server/handler/SSLReadWriteSelectorHandler.java
boolean doHandshake(SelectionKey sk) throws IOException {

        SSLEngineResult result;

        if (initialHSComplete) {
            return true;
        }

	/*
     * Flush out the outgoing buffer, if there's anything left in
	 * it.
	 */
        if (outNetBB.hasRemaining()) {

            if (!tryFlush(outNetBB)) {
                return false;
            }

            // See if we need to switch from write to read mode.

            switch (initialHSStatus) {

	    /*
         * Is this the last buffer?
	     */
                case FINISHED:
                    initialHSComplete = true;
                    // Fall-through to reregister need for a Read.

                case NEED_UNWRAP:
                    if (sk != null) {
                        sk.interestOps(SelectionKey.OP_READ);
                    }
                    break;
            }

            return initialHSComplete;
        }


        switch (initialHSStatus) {

            case NEED_UNWRAP:
                if (sc.read(inNetBB) == -1) {
                    sslEngine.closeInbound();
                    return initialHSComplete;
                }

                needIO:
                while (initialHSStatus == HandshakeStatus.NEED_UNWRAP) {
        /*
         * Don't need to resize requestBB, since no app data should
		 * be generated here.
		 */
                    inNetBB.flip();
                    result = sslEngine.unwrap(inNetBB, requestBB);
                    inNetBB.compact();

                    initialHSStatus = result.getHandshakeStatus();

                    switch (result.getStatus()) {

                        case OK:
                            switch (initialHSStatus) {
                                case NOT_HANDSHAKING:
                                    throw new IOException(
                                            "Not handshaking during initial handshake");

                                case NEED_TASK:
                                    initialHSStatus = doTasks();
                                    break;

                                case FINISHED:
                                    initialHSComplete = true;
                                    break needIO;
                            }

                            break;

                        case BUFFER_UNDERFLOW:
            /*
             * Need to go reread the Channel for more data.
		     */
                            if (sk != null) {
                                sk.interestOps(SelectionKey.OP_READ);
                            }
                            break needIO;

                        default: // BUFFER_OVERFLOW/CLOSED:
                            throw new IOException("Received" + result.getStatus() +
                                    "during initial handshaking");
                    }
                }  // "needIO" block.

	    /*
         * Just transitioned from read to write.
	     */
                if (initialHSStatus != HandshakeStatus.NEED_WRAP) {
                    break;
                }

                // Fall through and fill the write buffers.

            case NEED_WRAP:
        /*
         * The flush above guarantees the out buffer to be empty
	     */
                outNetBB.clear();
                result = sslEngine.wrap(hsBB, outNetBB);
                outNetBB.flip();

                initialHSStatus = result.getHandshakeStatus();

                switch (result.getStatus()) {
                    case OK:

                        if (initialHSStatus == HandshakeStatus.NEED_TASK) {
                            initialHSStatus = doTasks();
                        }

                        if (sk != null) {
                            sk.interestOps(SelectionKey.OP_WRITE);
                        }

                        break;

                    default: // BUFFER_OVERFLOW/BUFFER_UNDERFLOW/CLOSED:
                        throw new IOException("Received" + result.getStatus() +
                                "during initial handshaking");
                }
                break;

            default: // NOT_HANDSHAKING/NEED_TASK/FINISHED
                throw new RuntimeException("Invalid Handshaking State" +
                        initialHSStatus);
        } // switch

        return initialHSComplete;
    }
boolean doHandshake(SelectionKey sk) throws IOException {

        SSLEngineResult result;

        if (initialHSComplete) {
            return true;
        }

	/*
     * Flush out the outgoing buffer, if there's anything left in
	 * it.
	 */
        if (outNetBB.hasRemaining()) {

            if (!tryFlush(outNetBB)) {
                return false;
            }

            // See if we need to switch from write to read mode.

            switch (initialHSStatus) {

	    /*
         * Is this the last buffer?
	     */
                case FINISHED:
                    initialHSComplete = true;
                    // Fall-through to reregister need for a Read.

                case NEED_UNWRAP:
                    if (sk != null) {
                        sk.interestOps(SelectionKey.OP_READ);
                    }
                    break;
            }

            return initialHSComplete;
        }


        switch (initialHSStatus) {

            case NEED_UNWRAP:
                if (sc.read(inNetBB) == -1) {
                    sslEngine.closeInbound();
                    return initialHSComplete;
                }

                needIO:
                while (initialHSStatus == HandshakeStatus.NEED_UNWRAP) {
        /*
         * Don't need to resize requestBB, since no app data should
		 * be generated here.
		 */
                    inNetBB.flip();
                    result = sslEngine.unwrap(inNetBB, requestBB);
                    inNetBB.compact();

                    initialHSStatus = result.getHandshakeStatus();

                    switch (result.getStatus()) {

                        case OK:
                            switch (initialHSStatus) {
                                case NOT_HANDSHAKING:
                                    throw new IOException(
                                            "Not handshaking during initial handshake");

                                case NEED_TASK:
                                    initialHSStatus = doTasks();
                                    break;

                                case FINISHED:
                                    initialHSComplete = true;
                                    break needIO;
                            }

                            break;

                        case BUFFER_UNDERFLOW:
            /*
             * Need to go reread the Channel for more data.
		     */
                            if (sk != null) {
                                sk.interestOps(SelectionKey.OP_READ);
                            }
                            break needIO;

                        default: // BUFFER_OVERFLOW/CLOSED:
                            throw new IOException("Received" + result.getStatus() +
                                    "during initial handshaking");
                    }
                }  // "needIO" block.

	    /*
         * Just transitioned from read to write.
	     */
                if (initialHSStatus != HandshakeStatus.NEED_WRAP) {
                    break;
                }

                // Fall through and fill the write buffers.

            case NEED_WRAP:
        /*
         * The flush above guarantees the out buffer to be empty
	     */
                outNetBB.clear();
                result = sslEngine.wrap(hsBB, outNetBB);
                outNetBB.flip();

                initialHSStatus = result.getHandshakeStatus();

                switch (result.getStatus()) {
                    case OK:

                        if (initialHSStatus == HandshakeStatus.NEED_TASK) {
                            initialHSStatus = doTasks();
                        }

                        if (sk != null) {
                            sk.interestOps(SelectionKey.OP_WRITE);
                        }

                        break;

                    default: // BUFFER_OVERFLOW/BUFFER_UNDERFLOW/CLOSED:
                        throw new IOException("Received" + result.getStatus() +
                                "during initial handshaking");
                }
                break;

            default: // NOT_HANDSHAKING/NEED_TASK/FINISHED
                throw new RuntimeException("Invalid Handshaking State" +
                        initialHSStatus);
        } // switch

        return initialHSComplete;
    }
/*
Perform any handshaking processing.
<P>
If a SelectionKey is passed, register for selectable
operations.
<P>
In the blocking case, our caller will keep calling us until
we finish the handshake.  Our reads/writes will block as expected.
<P>
In the non-blocking case, we just received the selection notification
that this channel is ready for whatever the operation is, so give
it a try.
<P>
return:
true when handshake is done.
false while handshake is in progress