private Table<String, MetricDto, MeasureDto> searchMeasuresByComponentUuidAndMetric(
      DbSession dbSession,
      ComponentDto baseComponent,
      List<ComponentDto> components,
      List<MetricDto> metrics,
      List<WsMeasures.Period> periods,
      @Nullable Long developerId) {
    List<String> componentUuids = new ArrayList<>();
    componentUuids.add(baseComponent.uuid());
    components.stream().forEach(c -> componentUuids.add(c.uuid()));

    Map<Integer, MetricDto> metricsById = Maps.uniqueIndex(metrics, MetricDtoFunctions.toId());
    MeasureQuery measureQuery =
        MeasureQuery.builder()
            .setPersonId(developerId)
            .setComponentUuids(componentUuids)
            .setMetricIds(metricsById.keySet())
            .build();
    List<MeasureDto> measureDtos = dbClient.measureDao().selectByQuery(dbSession, measureQuery);

    Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric =
        HashBasedTable.create(components.size(), metrics.size());
    for (MeasureDto measureDto : measureDtos) {
      measuresByComponentUuidAndMetric.put(
          measureDto.getComponentUuid(), metricsById.get(measureDto.getMetricId()), measureDto);
    }

    addBestValuesToMeasures(measuresByComponentUuidAndMetric, components, metrics, periods);

    return measuresByComponentUuidAndMetric;
  }
  /**
   * Conditions for best value measure:
   *
   * <ul>
   *   <li>component is a production file or test file
   *   <li>metric is optimized for best value
   * </ul>
   */
  private static void addBestValuesToMeasures(
      Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric,
      List<ComponentDto> components,
      List<MetricDto> metrics,
      List<WsMeasures.Period> periods) {
    List<MetricDtoWithBestValue> metricDtosWithBestValueMeasure =
        from(metrics)
            .filter(MetricDtoFunctions.isOptimizedForBestValue())
            .transform(new MetricDtoToMetricDtoWithBestValue(periods))
            .toList();
    if (metricDtosWithBestValueMeasure.isEmpty()) {
      return;
    }

    List<ComponentDto> componentsEligibleForBestValue =
        from(components).filter(IsFileComponent.INSTANCE).toList();
    for (ComponentDto component : componentsEligibleForBestValue) {
      for (MetricDtoWithBestValue metricWithBestValue : metricDtosWithBestValueMeasure) {
        if (measuresByComponentUuidAndMetric.get(component.uuid(), metricWithBestValue.getMetric())
            == null) {
          measuresByComponentUuidAndMetric.put(
              component.uuid(),
              metricWithBestValue.getMetric(),
              metricWithBestValue.getBestValue());
        }
      }
    }
  }
  private List<MetricDto> searchMetrics(DbSession dbSession, ComponentTreeWsRequest request) {
    List<String> metricKeys = requireNonNull(request.getMetricKeys());
    List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
    if (metrics.size() < metricKeys.size()) {
      List<String> foundMetricKeys = Lists.transform(metrics, MetricDtoFunctions.toKey());
      Set<String> missingMetricKeys =
          Sets.difference(new LinkedHashSet<>(metricKeys), new LinkedHashSet<>(foundMetricKeys));

      throw new NotFoundException(
          format(
              "The following metric keys are not found: %s",
              Joiner.on(", ").join(missingMetricKeys)));
    }

    return metrics;
  }