public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) {
    Objects.requireNonNull(skipPast, "skipPast must not be null");
    Objects.requireNonNull(type, "type must not be null");

    if (jsonAdapterFactory.isClassJsonAdapterFactory(type, skipPast)) {
      skipPast = jsonAdapterFactory;
    }

    boolean skipPastFound = false;
    for (TypeAdapterFactory factory : factories) {
      if (!skipPastFound) {
        if (factory == skipPast) {
          skipPastFound = true;
        }
        continue;
      }

      TypeAdapter<T> candidate = factory.create(this, type);
      if (candidate != null) {
        return candidate;
      }
    }

    if (skipPastFound) {
      throw new IllegalArgumentException("GSON cannot serialize or deserialize " + type);
    } else {
      // Probably a factory from @JsonAdapter on a field
      return getAdapter(type);
    }
  }
@Test
  public void testGetDelegateAdapter() {
    class DummyAdapter extends TypeAdapter<Number> {
      private final int number;

      DummyAdapter(int number) {
        this.number = number;
      }

      @Override
      public Number read(JsonReader in) throws IOException {
        throw new AssertionError("not needed for test");
      }

      @Override
      public void write(JsonWriter out, Number value) throws IOException {
        throw new AssertionError("not needed for test");
      }

      // Override toString() for better assertion error messages
      @Override
      public String toString() {
        return "adapter-" + number;
      }
    }

    class DummyFactory implements TypeAdapterFactory {
      private final DummyAdapter adapter;

      DummyFactory(DummyAdapter adapter) {
        this.adapter = adapter;
      }

      @SuppressWarnings("unchecked")
      @Override
      public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        return (TypeAdapter<T>) adapter;
      }

      // Override equals to verify that reference equality check is performed by Gson,
      // and this method is ignored
      @Override
      public boolean equals(Object obj) {
        return obj instanceof DummyFactory && ((DummyFactory) obj).adapter.equals(adapter);
      }

      @Override
      public int hashCode() {
        return adapter.hashCode();
      }
    }

    DummyAdapter adapter1 = new DummyAdapter(1);
    DummyFactory factory1 = new DummyFactory(adapter1);
    DummyAdapter adapter2 = new DummyAdapter(2);
    DummyFactory factory2 = new DummyFactory(adapter2);

    Gson gson =
        new GsonBuilder()
            // Note: This is 'last in, first out' order; Gson will first use factory2, then factory1
            .registerTypeAdapterFactory(factory1)
            .registerTypeAdapterFactory(factory2)
            .create();

    TypeToken<?> type = TypeToken.get(Number.class);

    assertThrows(NullPointerException.class, () -> gson.getDelegateAdapter(null, type));
    assertThrows(NullPointerException.class, () -> gson.getDelegateAdapter(factory1, null));

    // For unknown factory the first adapter for that type should be returned
    assertThat(gson.getDelegateAdapter(new DummyFactory(new DummyAdapter(0)), type))
        .isEqualTo(adapter2);

    assertThat(gson.getDelegateAdapter(factory2, type)).isEqualTo(adapter1);
    // Default Gson adapter should be returned
    assertThat(gson.getDelegateAdapter(factory1, type)).isNotInstanceOf(DummyAdapter.class);

    DummyFactory factory1Eq = new DummyFactory(adapter1);
    // Verify that test setup is correct
    assertThat(factory1.equals(factory1Eq)).isTrue();
    // Should only consider reference equality and ignore that custom `equals` method considers
    // factories to be equal, therefore returning `adapter2` which came from `factory2` instead
    // of skipping past `factory1`
    assertThat(gson.getDelegateAdapter(factory1Eq, type)).isEqualTo(adapter2);
  }