@Override
  public Extension newInstance(ExtensionConfig config) {
    if (config == null) {
      return null;
    }

    String name = config.getName();
    if (StringUtil.isBlank(name)) {
      return null;
    }

    Class<? extends Extension> extClass = getExtension(name);
    if (extClass == null) {
      return null;
    }

    try {
      Extension ext = extClass.newInstance();
      if (ext instanceof AbstractExtension) {
        AbstractExtension aext = (AbstractExtension) ext;
        aext.setConfig(config);
        aext.setPolicy(policy);
        aext.setBufferPool(bufferPool);
      }
      return ext;
    } catch (InstantiationException | IllegalAccessException e) {
      throw new WebSocketException("Cannot instantiate extension: " + extClass, e);
    }
  }
  @Override
  public void setConfig(final ExtensionConfig config) {
    configRequested = new ExtensionConfig(config);
    configNegotiated = new ExtensionConfig(config.getName());

    for (String key : config.getParameterKeys()) {
      key = key.trim();
      switch (key) {
        case "client_max_window_bits":
        case "server_max_window_bits":
          {
            // Not supported by Jetty
            // Don't negotiate these parameters
            break;
          }
        case "client_no_context_takeover":
          {
            configNegotiated.setParameter("client_no_context_takeover");
            switch (getPolicy().getBehavior()) {
              case CLIENT:
                incomingContextTakeover = false;
                break;
              case SERVER:
                outgoingContextTakeover = false;
                break;
            }
            break;
          }
        case "server_no_context_takeover":
          {
            configNegotiated.setParameter("server_no_context_takeover");
            switch (getPolicy().getBehavior()) {
              case CLIENT:
                outgoingContextTakeover = false;
                break;
              case SERVER:
                incomingContextTakeover = false;
                break;
            }
            break;
          }
        default:
          {
            throw new IllegalArgumentException();
          }
      }
    }

    super.setConfig(configNegotiated);
  }
  @Override
  public void initializeNativeSession(Session session) {
    super.initializeNativeSession(session);

    this.id = ObjectUtils.getIdentityHexString(getNativeSession());
    this.uri = session.getUpgradeRequest().getRequestURI();

    this.headers = new HttpHeaders();
    this.headers.putAll(getNativeSession().getUpgradeRequest().getHeaders());
    this.headers = HttpHeaders.readOnlyHttpHeaders(headers);

    this.acceptedProtocol = session.getUpgradeResponse().getAcceptedSubProtocol();

    List<ExtensionConfig> source = getNativeSession().getUpgradeResponse().getExtensions();
    this.extensions = new ArrayList<WebSocketExtension>(source.size());
    for (ExtensionConfig ec : source) {
      this.extensions.add(new WebSocketExtension(ec.getName(), ec.getParameters()));
    }

    if (this.user == null) {
      this.user = session.getUpgradeRequest().getUserPrincipal();
    }
  }