@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 decodes() throws Exception {

    class Zone extends LinkedHashMap<String, Object> {

      Zone(String name) {
        this(name, null);
      }

      Zone(String name, String id) {
        put("name", name);
        if (id != null) {
          put("id", id);
        }
      }

      private static final long serialVersionUID = 1L;
    }

    List<Zone> zones = new LinkedList<>();
    zones.add(new Zone("denominator.io."));
    zones.add(new Zone("denominator.io.", "ABCD"));

    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(zonesJson, UTF_8)
        .build();

    assertThat(new MoshiDecoder().decode(response, List.class)).isEqualTo(zones);
  }