@Override
    public WebSocketClientExtension handshakeExtension(WebSocketExtensionData extensionData) {
        if (!PERMESSAGE_DEFLATE_EXTENSION.equals(extensionData.name())) {
            return null;
        }

        boolean succeed = true;
        int clientWindowSize = MAX_WINDOW_SIZE;
        int serverWindowSize = MAX_WINDOW_SIZE;
        boolean serverNoContext = false;
        boolean clientNoContext = false;

        Iterator<Entry<String, String>> parametersIterator =
                extensionData.parameters().entrySet().iterator();
        while (succeed && parametersIterator.hasNext()) {
            Entry<String, String> parameter = parametersIterator.next();

            if (CLIENT_MAX_WINDOW.equalsIgnoreCase(parameter.getKey())) {
                // allowed client_window_size_bits
                if (allowClientWindowSize) {
                    clientWindowSize = Integer.parseInt(parameter.getValue());
                    if (clientWindowSize > MAX_WINDOW_SIZE || clientWindowSize < MIN_WINDOW_SIZE) {
                        succeed = false;
                    }
                } else {
                    succeed = false;
                }
            } else if (SERVER_MAX_WINDOW.equalsIgnoreCase(parameter.getKey())) {
                // acknowledged server_window_size_bits
                serverWindowSize = Integer.parseInt(parameter.getValue());
                if (serverWindowSize > MAX_WINDOW_SIZE || serverWindowSize < MIN_WINDOW_SIZE) {
                    succeed = false;
                }
            } else if (CLIENT_NO_CONTEXT.equalsIgnoreCase(parameter.getKey())) {
                // allowed client_no_context_takeover
                if (allowClientNoContext) {
                    clientNoContext = true;
                } else {
                    succeed = false;
                }
            } else if (SERVER_NO_CONTEXT.equalsIgnoreCase(parameter.getKey())) {
                // acknowledged server_no_context_takeover
                serverNoContext = true;
            } else {
                // unknown parameter
                succeed = false;
            }
        }

        if ((requestedServerNoContext && !serverNoContext) ||
                requestedServerWindowSize < serverWindowSize) {
            succeed = false;
        }

        if (succeed) {
            return new PermessageDeflateExtension(serverNoContext, serverWindowSize,
                    clientNoContext, clientWindowSize, extensionFilterProvider);
        } else {
            return null;
        }
    }
@Test
    public void testServerNoContextTakeover() {
        WebSocketClientExtension extension;
        Map<String, String> parameters;

        PerMessageDeflateClientExtensionHandshaker handshaker =
                new PerMessageDeflateClientExtensionHandshaker(6, true, 15, true, false);

        parameters = new HashMap<String, String>();
        parameters.put(SERVER_NO_CONTEXT, null);
        extension = handshaker.handshakeExtension(new WebSocketExtensionData(PERMESSAGE_DEFLATE_EXTENSION, parameters));

        // Test that handshake succeeds when server responds with `server_no_context_takeover` that we didn't offer
        assertNotNull(extension);
        assertEquals(RSV1, extension.rsv());
        assertTrue(extension.newExtensionDecoder() instanceof PerMessageDeflateDecoder);
        assertTrue(extension.newExtensionEncoder() instanceof PerMessageDeflateEncoder);

        // initialize
        handshaker = new PerMessageDeflateClientExtensionHandshaker(6, true, 15, true, true);

        parameters = new HashMap<String, String>();
        extension = handshaker.handshakeExtension(new WebSocketExtensionData(PERMESSAGE_DEFLATE_EXTENSION, parameters));

        // Test that handshake fails when client offers `server_no_context_takeover` but server doesn't support it
        assertNull(extension);
    }