@Override
  public Response intercept(Chain chain) throws IOException {
    String requestId = String.valueOf(mNextRequestId.getAndIncrement());

    Request request = chain.request();

    int requestSize = 0;
    if (mEventReporter.isEnabled()) {
      OkHttpInspectorRequest inspectorRequest = new OkHttpInspectorRequest(requestId, request);
      mEventReporter.requestWillBeSent(inspectorRequest);
      byte[] requestBody = inspectorRequest.body();
      if (requestBody != null) {
        requestSize += requestBody.length;
      }
    }

    Response response;
    try {
      response = chain.proceed(request);
    } catch (IOException e) {
      if (mEventReporter.isEnabled()) {
        mEventReporter.httpExchangeFailed(requestId, e.toString());
      }
      throw e;
    }

    if (mEventReporter.isEnabled()) {
      if (requestSize > 0) {
        mEventReporter.dataSent(requestId, requestSize, requestSize);
      }

      Connection connection = chain.connection();
      mEventReporter.responseHeadersReceived(
          new OkHttpInspectorResponse(requestId, request, response, connection));

      ResponseBody body = response.body();
      MediaType contentType = null;
      InputStream responseStream = null;
      if (body != null) {
        contentType = body.contentType();
        responseStream = body.byteStream();
      }

      responseStream =
          mEventReporter.interpretResponseStream(
              requestId,
              contentType != null ? contentType.toString() : null,
              response.header("Content-Encoding"),
              responseStream,
              new DefaultResponseHandler(mEventReporter, requestId));
      if (responseStream != null) {
        response =
            response.newBuilder().body(new ForwardingResponseBody(body, responseStream)).build();
      }
    }

    return response;
  }