protected function receiveServerHandshake(
        array $headers,
        $nonce,
        array $protocols = array()
    ) {
        // Make sure required headers and values are present as per RFC 6455
        // section 4.1 client validation of server response.
        if (!isset($headers['Sec-WebSocket-Accept'])) {
            throw new Net_Notifier_WebSocket_HandshakeFailureException(
                'Sec-WebSocket-Accept header missing.'
            );
        }

        if (   !isset($headers['Upgrade'])
            || mb_strtolower($headers['Upgrade']) !== 'websocket'
        ) {
            throw new Net_Notifier_WebSocket_HandshakeFailureException(
                'Upgrade header missing or not set to "websocket".'
            );
        }

        if (   !isset($headers['Connection'])
            || mb_strtolower($headers['Connection']) !== 'upgrade'
        ) {
            throw new Net_Notifier_WebSocket_HandshakeFailureException(
                'Connection header missing or not set to "Upgrade".'
            );
        }

        // Make sure server responded with appropriate Sec-WebSocket-Accept
        // header. Ignore leading and trailing whitespace as per RFC 6455
        // section 4.1 client validation of server response item 4.
        $responseAccept = trim($headers['Sec-WebSocket-Accept']);
        $validAccept = $this->getAccept($nonce);
        if ($responseAccept !== $validAccept) {
            throw new Net_Notifier_WebSocket_HandshakeFailureException(
                sprintf(
                    'Sec-WebSocket-Accept header "%s" does not validate '
                    . 'against nonce "%s"',
                    $responseAccept,
                    $nonce
                )
            );
        }

        // If specific subprotocols were requested, verify the server supports
        // them. See RFC 6455 Section 4.1 server response validation item 6.
        if (count($protocols) > 0) {
            if (!isset($headers['Sec-WebSocket-Protocol'])) {
                throw new Net_Notifier_WebSocket_ProtocolException(
                    sprintf(
                        "Client requested '%s' sub-protocols but server does "
                        . "not support any of them.",
                        implode(' ', $protocols)
                    ),
                    0,
                    null,
                    $protocols
                );
            }

            if (!in_array($headers['Sec-WebSocket-Protocol'], $protocols)) {
                throw new Net_Notifier_WebSocket_ProtocolException(
                    sprintf(
                        "Client requested '%s' sub-protocols. Server "
                        . "responded with unsupported sub-protocol: '%s'.",
                        implode(' ', $protocols),
                        $headers['Sec-WebSocket-Protocol']
                    ),
                    0,
                    $headers['Sec-WebSocket-Protocol'],
                    $protocols
                );
            }
        }

        return null;
    }