class CurveSensitivityUtils {

  public static CurrencyParameterSensitivities linearRebucketing(
      CurrencyParameterSensitivities sensitivities,
      List<LocalDate> targetDates) {

    checkSortedDates(targetDates);
    int nbBuckets = targetDates.size();
    List<ParameterMetadata> pmdTarget = targetDates.stream()
        .map(date -> LabelDateParameterMetadata.of(date, date.toString()))
        .collect(toList());
    ImmutableList<CurrencyParameterSensitivity> sensitivitiesList = sensitivities.getSensitivities();
    List<CurrencyParameterSensitivity> sensitivityTarget = new ArrayList<>();
    for (CurrencyParameterSensitivity sensitivity : sensitivitiesList) {
      double[] rebucketedSensitivityAmounts = new double[nbBuckets];
      DoubleArray sensitivityAmounts = sensitivity.getSensitivity();
      List<ParameterMetadata> parameterMetadataList = sensitivity.getParameterMetadata();
      for (int loopnode = 0; loopnode < sensitivityAmounts.size(); loopnode++) {
        ParameterMetadata nodeMetadata = parameterMetadataList.get(loopnode);
        ArgChecker.isTrue(nodeMetadata instanceof DatedParameterMetadata,
            "re-bucketing requires sensitivity date for node {} which is of type {} while 'DatedParameterMetadata' is expected",
            nodeMetadata.getLabel(), nodeMetadata.getClass().getName());
        DatedParameterMetadata datedParameterMetadata = (DatedParameterMetadata) nodeMetadata;
        LocalDate nodeDate = datedParameterMetadata.getDate();
        rebucketingArray(targetDates, rebucketedSensitivityAmounts, sensitivityAmounts.get(loopnode), nodeDate);
      }
      CurrencyParameterSensitivity rebucketedSensitivity = CurrencyParameterSensitivity.of(
          sensitivity.getMarketDataName(),
          pmdTarget,
          sensitivity.getCurrency(),
          DoubleArray.ofUnsafe(rebucketedSensitivityAmounts));
      sensitivityTarget.add(rebucketedSensitivity);
    }
    return CurrencyParameterSensitivities.of(sensitivityTarget);
  }

  private  CurveSensitivityUtils();

}