class KubernetesMockServerExtension
    implements AfterEachCallback, AfterAllCallback, BeforeEachCallback, BeforeAllCallback {

  private KubernetesMockServer staticMock;
  private NamespacedKubernetesClient staticClient;
  private KubernetesMockServer instantMock;
  private NamespacedKubernetesClient instantClient;

  public interface SetTestClassField {
    void apply(Object instance, Field f) throws IllegalAccessException;
  }

  @Override
  public void afterEach(ExtensionContext context) {
    destroy();
  }

  @Override
  public void afterAll(ExtensionContext context) {
    destroyStatic();
  }

  @Override
  public void beforeEach(ExtensionContext context) throws Exception {
    setKubernetesClientAndMockServerFields(context, false);
  }

  @Override
  public void beforeAll(ExtensionContext context) throws Exception {
    setKubernetesClientAndMockServerFields(context, true);
  }

  protected void setFieldIfKubernetesClientOrMockServer(ExtensionContext context, boolean isStatic, Field field)
      throws IllegalAccessException {
    if (extensionMatches(field.getType())) {
      final NamespacedKubernetesClient client;
      if (isStatic) {
        client = staticClient;
      } else {
        client = instantClient;
      }
      setFieldIfEqualsToProvidedType(context, isStatic, field, Client.class,
          (i, f) -> f.set(i, client.adapt((Class<Client>) f.getType())));
    } else {
      final KubernetesMockServer mock;
      if (isStatic) {
        mock = staticMock;
      } else {
        mock = instantMock;
      }
      setFieldIfEqualsToProvidedType(context, isStatic, field, getKubernetesMockServerType(), (i, f) -> f.set(i, mock));
    }
  }

  protected void setFieldIfEqualsToProvidedType(ExtensionContext context, boolean isStatic, Field field, Class<?> fieldType,
      SetTestClassField setTestClassField) throws IllegalAccessException {
    if (fieldType.isAssignableFrom(field.getType()) && Modifier.isStatic(field.getModifiers()) == isStatic) {
      setKubernetesClientStaticOrMemberField(context, isStatic, field, setTestClassField);
    }
  }

  protected void initializeKubernetesClientAndMockServer(Class<?> testClass, boolean isStatic) {
    EnableKubernetesMockClient a = testClass.getAnnotation(EnableKubernetesMockClient.class);
    final Map<ServerRequest, Queue<ServerResponse>> responses = new HashMap<>();
    final Dispatcher dispatcher;
    if (a.crud()) {
      dispatcher = new KubernetesMixedDispatcher(responses);
    } else {
      dispatcher = new MockDispatcher(responses);
    }
    final KubernetesMockServer mock = new KubernetesMockServer(new Context(Serialization.jsonMapper()),
        new MockWebServer(), responses, dispatcher, a.https());
    mock.init();
    if (isStatic) {
      staticMock = mock;
    } else {
      instantMock = mock;
    }
    try {
      final NamespacedKubernetesClient client = mock.createClient(
          a.kubernetesClientBuilderCustomizer().getConstructor().newInstance());
      if (isStatic) {
        staticClient = client;
      } else {
        instantClient = client;
      }
    } catch (Exception e) {
      throw new IllegalArgumentException("The provided kubernetesClientBuilder is invalid", e);
    }
  }

  protected void destroy() {<FILL_FUNCTION_BODY>}

  protected void destroyStatic() {
    staticMock.destroy();
    staticClient.close();
  }

  /**
   * @deprecated no longer used
   */
  @Deprecated
  protected Class<?> getClientType() {
    return KubernetesClient.class;
  }

  protected Class<?> getKubernetesMockServerType() {
    return KubernetesMockServer.class;
  }

  private boolean extensionMatches(Class<?> type) {
    return Client.class.isAssignableFrom(type);
  }

  private void setKubernetesClientAndMockServerFields(ExtensionContext context, boolean isStatic)
      throws IllegalAccessException {
    Optional<Class<?>> optClass = context.getTestClass();
    if (optClass.isPresent()) {
      Class<?> testClass = optClass.get();
      initializeKubernetesClientAndMockServer(testClass, isStatic);
      processTestClassDeclaredFields(context, isStatic, testClass);
    }
  }

  private void processTestClassDeclaredFields(ExtensionContext context, boolean isStatic, Class<?> testClass)
      throws IllegalAccessException {
    Field[] fields = testClass.getDeclaredFields();
    for (Field field : fields) {
      setFieldIfKubernetesClientOrMockServer(context, isStatic, field);
    }
  }

  private void setKubernetesClientStaticOrMemberField(ExtensionContext context, boolean isStatic, Field f,
      SetTestClassField setTestClassField) throws IllegalAccessException {
    f.setAccessible(true);
    if (isStatic) {
      setTestClassField.apply(null, f);
    } else {
      Optional<Object> optTestInstance = context.getTestInstance();
      if (optTestInstance.isPresent())
        setTestClassField.apply(optTestInstance.get(), f);
    }
  }
}

    if (instantMock != null) {
      instantMock.destroy();
    }
    if (instantClient != null) {
      instantClient.close();
    }
  
<no_super_class>