private void removeOldRequestTraces(ConcurrentLinkedQueue<HttpRequestTrace> httpRequestTraces) {
   for (Iterator<HttpRequestTrace> iterator = httpRequestTraces.iterator();
       iterator.hasNext(); ) {
     HttpRequestTrace httpRequestTrace = iterator.next();
     final long timeInBuffer = System.currentTimeMillis() - httpRequestTrace.getTimestampEnd();
     if (timeInBuffer > MAX_REQUEST_TRACE_BUFFERING_TIME) {
       iterator.remove();
     }
   }
 }
  private void bufferRequestTrace(String connectionId, HttpRequestTrace requestTrace) {
    logger.debug("bufferRequestTrace {} ({})", requestTrace.getName(), requestTrace.getTimestamp());
    ConcurrentLinkedQueue<HttpRequestTrace> httpRequestTraces =
        new ConcurrentLinkedQueue<HttpRequestTrace>();
    httpRequestTraces.add(requestTrace);

    final ConcurrentLinkedQueue<HttpRequestTrace> alreadyAssociatedValue =
        connectionIdToRequestTracesMap.putIfAbsent(connectionId, httpRequestTraces);
    if (alreadyAssociatedValue != null) {
      alreadyAssociatedValue.add(requestTrace);
    }
  }
  @Override
  public void reportRequestTrace(ReportArguments reportArguments) throws IOException {
    if (isActive(new IsActiveArguments(reportArguments.getRequestTrace()))
        && reportArguments.getRequestTrace() instanceof HttpRequestTrace) {
      HttpRequestTrace httpRequestTrace = (HttpRequestTrace) reportArguments.getRequestTrace();

      final String connectionId = httpRequestTrace.getConnectionId();
      if (connectionId != null && !connectionId.trim().isEmpty()) {
        logger.debug(
            "reportRequestTrace {} ({})",
            reportArguments.getRequestTrace().getName(),
            reportArguments.getRequestTrace().getTimestamp());
        bufferRequestTrace(connectionId, httpRequestTrace);

        final Object lock = connectionIdToLockMap.remove(connectionId);
        if (lock != null) {
          synchronized (lock) {
            lock.notifyAll();
          }
        }
      }
    }
  }