void initializeFilter(HeaderMode mode, bool inject_route_config_headers) {
    config_helper_.addConfigModifier(
        [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
                hcm) {
          // Overwrite default config with our own.
          TestUtility::loadFromYaml(http_connection_mgr_config, hcm);
          envoy::extensions::filters::http::router::v3::Router router_config;
          router_config.set_suppress_envoy_headers(routerSuppressEnvoyHeaders());
          hcm.mutable_http_filters(0)->mutable_typed_config()->PackFrom(router_config);

          const bool append = mode == HeaderMode::Append;

          auto* route_config = hcm.mutable_route_config();
          if (inject_route_config_headers) {
            // Configure route config level headers.
            addHeader(route_config->mutable_response_headers_to_add(), "x-routeconfig-response",
                      "routeconfig", append);
            route_config->add_response_headers_to_remove("x-routeconfig-response-remove");
            addHeader(route_config->mutable_request_headers_to_add(), "x-routeconfig-request",
                      "routeconfig", append);
            route_config->add_request_headers_to_remove("x-routeconfig-request-remove");
          }

          if (use_eds_) {
            addHeader(route_config->mutable_response_headers_to_add(), "x-routeconfig-dynamic",
                      R"(%UPSTREAM_METADATA(["test.namespace", "key"])%)", append);

            // Iterate over VirtualHosts, nested Routes and WeightedClusters, adding a dynamic
            // response header.
            for (auto& vhost : *route_config->mutable_virtual_hosts()) {
              addHeader(vhost.mutable_response_headers_to_add(), "x-vhost-dynamic",
                        R"(vhost:%UPSTREAM_METADATA(["test.namespace", "key"])%)", append);

              for (auto& route : *vhost.mutable_routes()) {
                addHeader(route.mutable_response_headers_to_add(), "x-route-dynamic",
                          R"(route:%UPSTREAM_METADATA(["test.namespace", "key"])%)", append);

                if (route.has_route()) {
                  auto* route_action = route.mutable_route();
                  if (route_action->has_weighted_clusters()) {
                    for (auto& c : *route_action->mutable_weighted_clusters()->mutable_clusters()) {
                      addHeader(c.mutable_response_headers_to_add(), "x-weighted-cluster-dynamic",
                                R"(weighted:%UPSTREAM_METADATA(["test.namespace", "key"])%)",
                                append);
                    }
                  }
                }
              }
            }
          }

          hcm.mutable_normalize_path()->set_value(normalize_path_);

          if (append) {
            // The config specifies append by default: no modifications needed.
            return;
          }

          // Iterate over VirtualHosts and nested Routes, disabling header append.
          for (auto& vhost : *route_config->mutable_virtual_hosts()) {
            disableHeaderValueOptionAppend(*vhost.mutable_request_headers_to_add());
            disableHeaderValueOptionAppend(*vhost.mutable_response_headers_to_add());

            for (auto& route : *vhost.mutable_routes()) {
              disableHeaderValueOptionAppend(*route.mutable_request_headers_to_add());
              disableHeaderValueOptionAppend(*route.mutable_response_headers_to_add());

              if (route.has_route()) {
                auto* route_action = route.mutable_route();

                if (route_action->has_weighted_clusters()) {
                  for (auto& c : *route_action->mutable_weighted_clusters()->mutable_clusters()) {
                    disableHeaderValueOptionAppend(*c.mutable_request_headers_to_add());
                    disableHeaderValueOptionAppend(*c.mutable_response_headers_to_add());
                  }
                }
              }
            }
          }
        });

    initialize();
  }