class SabrIborCapletFloorletPeriodPricer extends VolatilityIborCapletFloorletPeriodPricer {

  public PointSensitivityBuilder presentValueSensitivityModelParamsSabr(
      IborCapletFloorletPeriod period,
      RatesProvider ratesProvider,
      SabrIborCapletFloorletVolatilities volatilities) {

    double expiry = volatilities.relativeTime(period.getFixingDateTime());
    if (expiry < 0d) { // option expired already
      return PointSensitivityBuilder.none();
    }
    Currency currency = period.getCurrency();
    PutCall putCall = period.getPutCall();
    double strike = period.getStrike();
    double indexRate = ratesProvider.iborIndexRates(period.getIndex()).rate(period.getIborRate().getObservation());
    double factor = period.getNotional() * period.getYearFraction();
    ValueDerivatives volatilityAdj = volatilities.volatilityAdjoint(expiry, strike, indexRate);
    DoubleArray derivative = volatilityAdj.getDerivatives();
    double df = ratesProvider.discountFactor(currency, period.getPaymentDate());
    double vega = df * factor * volatilities.priceVega(expiry, putCall, strike, indexRate, volatilityAdj.getValue());
    IborCapletFloorletVolatilitiesName name = volatilities.getName();

    return PointSensitivityBuilder.of(
        IborCapletFloorletSabrSensitivity.of(name, expiry, ALPHA, currency, vega * derivative.get(2)),
        IborCapletFloorletSabrSensitivity.of(name, expiry, BETA, currency, vega * derivative.get(3)),
        IborCapletFloorletSabrSensitivity.of(name, expiry, RHO, currency, vega * derivative.get(4)),
        IborCapletFloorletSabrSensitivity.of(name, expiry, NU, currency, vega * derivative.get(5)));
  }

}