class KubernetesClientBuilder {

  @FunctionalInterface
  public interface ExecutorSupplier extends Supplier<Executor> {

    default void onClose(Executor executor) {

    }

  }

  private Config config;
  private HttpClient.Factory factory;
  private Class<KubernetesClient> clazz;
  private ExecutorSupplier executorSupplier;
  private Consumer<HttpClient.Builder> builderConsumer;
  private KubernetesSerialization kubernetesSerialization = new KubernetesSerialization();

  public KubernetesClientBuilder() {
    // basically the same logic as in KubernetesResourceUtil for finding list types
    String className = "io.fabric8.kubernetes.client.impl.KubernetesClientImpl";
    try {
      clazz = (Class<KubernetesClient>) Thread.currentThread().getContextClassLoader().loadClass(className);
    } catch (ClassNotFoundException | ClassCastException | NullPointerException e) {
      try {
        clazz = (Class<KubernetesClient>) KubernetesClient.class.getClassLoader().loadClass(className);
      } catch (Exception ex) {
        throw KubernetesClientException.launderThrowable(ex);
      }
    }
  }

  KubernetesClientBuilder(Class<KubernetesClient> clazz) {
    this.clazz = clazz;
  }

  public KubernetesClient build() {<FILL_FUNCTION_BODY>}

  HttpClient getHttpClient() {
    HttpClient.Builder builder = factory.newBuilder(config);
    if (this.builderConsumer != null) {
      this.builderConsumer.accept(builder);
    }
    return builder.build();
  }

  public KubernetesClientBuilder withConfig(Config config) {
    this.config = config;
    return this;
  }

  public KubernetesClientBuilder withKubernetesSerialization(KubernetesSerialization kubernetesSerialization) {
    this.kubernetesSerialization = Utils.checkNotNull(kubernetesSerialization, "kubernetesSerialization must not be null");
    return this;
  }

  public KubernetesClientBuilder withConfig(String config) {
    this.config = kubernetesSerialization.unmarshal(config, Config.class);
    return this;
  }

  public KubernetesClientBuilder withConfig(InputStream config) {
    this.config = kubernetesSerialization.unmarshal(config, Config.class);
    return this;
  }

  public KubernetesClientBuilder withHttpClientFactory(HttpClient.Factory factory) {
    this.factory = factory;
    return this;
  }

  /**
   * Configure the client to use the given executor for async tasks, such as {@link ResourceEventHandler}
   * calls and writing to streams.
   * <p>
   * Only override if you need more control over the number of task threads used by the kubernetes client.
   *
   * @return this builder
   */
  public KubernetesClientBuilder withTaskExecutor(Executor executor) {
    this.executorSupplier = () -> executor;
    return this;
  }

  /**
   * Configure the client to use the given {@link ExecutorSupplier} for async tasks, such as {@link ResourceEventHandler}
   * calls and writing to streams.
   * <p>
   * There will be a call to {@link ExecutorSupplier#onClose(Executor)} when a client is closed.
   * <p>
   * Only override if you need more control over the number of task threads used by the kubernetes client.
   *
   * @return this builder
   */
  public KubernetesClientBuilder withTaskExecutorSupplier(ExecutorSupplier executorSupplier) {
    this.executorSupplier = executorSupplier;
    return this;
  }

  /**
   * Provide additional configuration for the {@link HttpClient} that is created for this {@link KubernetesClient}.
   *
   * @param consumer to modify the {@link HttpClient.Builder}
   * @return this builder
   */
  public KubernetesClientBuilder withHttpClientBuilderConsumer(Consumer<HttpClient.Builder> consumer) {
    this.builderConsumer = consumer;
    return this;
  }

  public class ConfigNested extends ConfigFluent<ConfigNested> {

    private ConfigBuilder builder;

    private ConfigNested() {
      this.builder = new ConfigBuilder(this, config);
    }

    public KubernetesClientBuilder endConfig() {
      config = this.builder.build();
      return KubernetesClientBuilder.this;
    }

  }

  public ConfigNested editOrNewConfig() {
    return new ConfigNested();
  }

}

    if (config == null) {
      config = new ConfigBuilder().build();
    }
    try {
      if (factory == null) {
        this.factory = HttpClientUtils.getHttpClientFactory();
      }
      HttpClient client = getHttpClient();
      return clazz.getConstructor(HttpClient.class, Config.class, ExecutorSupplier.class, KubernetesSerialization.class)
          .newInstance(client, config,
              executorSupplier, kubernetesSerialization);
    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
        | NoSuchMethodException | SecurityException e) {
      throw KubernetesClientException.launderThrowable(e);
    }
  
<no_super_class>