ArgumentChecker.notNull(dividends, "dividends");
ArgumentChecker.notNull(marketVols, "market volatilities");
final PureLocalVolatilitySurface plv = getPureLocalVolFromMarket(spot, discountCurve, dividends, marketVols);
final EquityDividendsCurvesBundle divCurves = new EquityDividendsCurvesBundle(spot, discountCurve, dividends);
final LocalVolatilitySurfaceStrike lv = VolatilitySurfaceConverter.convertLocalVolSurface(plv, divCurves);
final double eps = 1e-5;
final int index = swap.correctForDividends() ? 0 : 1;
final double t = swap.getTimeToSettlement();
//up
final LocalVolatilitySurfaceStrike lvUp = new LocalVolatilitySurfaceStrike(flooredShiftSurface(lv.getSurface(), eps));
final PureLocalVolatilitySurface plvUp = VolatilitySurfaceConverter.convertLocalVolSurface(lvUp, divCurves);
final double up = Math.sqrt(VAR_SWAP_FWD_PDE_CALCULATOR.expectedVariance(spot, discountCurve, dividends, t, plvUp)[index] / t);
//down
final LocalVolatilitySurfaceStrike lvDown = new LocalVolatilitySurfaceStrike(flooredShiftSurface(lv.getSurface(), -eps));
final PureLocalVolatilitySurface plvDown = VolatilitySurfaceConverter.convertLocalVolSurface(lvDown, divCurves);
final double down = Math.sqrt(VAR_SWAP_FWD_PDE_CALCULATOR.expectedVariance(spot, discountCurve, dividends, t, plvDown)[index] / t);
final double vega = (up - down) / 2 / eps;
return vega;
}