@Override
  public Object decode(Response response, Type type) throws IOException {
    JsonAdapter<Object> jsonAdapter = moshi.adapter(type);

    if (response.status() == 404 || response.status() == 204)
      return Util.emptyValueOf(type);
    if (response.body() == null)
      return null;

    try (BufferedSource source = Okio.buffer(Okio.source(response.body().asInputStream()))) {
      if (source.exhausted()) {
        return null; // empty body
      }
      return jsonAdapter.fromJson(source);
    } catch (JsonDataException e) {
      if (e.getCause() != null && e.getCause() instanceof IOException) {
        throw (IOException) e.getCause();
      }
      throw e;
    }
  }
@Test
  void customObjectDecoder() throws Exception {
    final JsonAdapter<VideoGame> videoGameJsonAdapter =
        new Moshi.Builder().build().adapter(VideoGame.class);

    MoshiDecoder decoder = new MoshiDecoder(Collections.singleton(videoGameJsonAdapter));

    VideoGame videoGame = new VideoGame("Super Mario", "Luigi", "Bowser");

    Response response =
        Response.builder()
            .status(200)
            .reason("OK")
            .headers(Collections.emptyMap())
            .request(
                Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null,
                    Util.UTF_8))
            .body(videoGamesJson, UTF_8)
            .build();

    VideoGame actual = (VideoGame) decoder.decode(response, videoGameJsonAdapter.getClass());

    assertThat(actual)
        .isEqualToComparingFieldByFieldRecursively(videoGame);
  }