final Surface<Double, Double, Double> surface = market.getVolatilitySurface().getSurface();
ArgumentChecker.isTrue(surface instanceof InterpolatedDoublesSurface, "Currently will only accept a Equity VolatilitySurfaces based on an InterpolatedDoublesSurface");
final InterpolatedDoublesSurface blackSurf = (InterpolatedDoublesSurface) surface;
final InterpolatedSurfaceAdditiveShiftFunction volShifter = new InterpolatedSurfaceAdditiveShiftFunction();
// shift UP
final InterpolatedDoublesSurface bumpedVolUp = volShifter.evaluate(blackSurf, maturity, strike, shift);
StaticReplicationDataBundle bumpedMarket = new StaticReplicationDataBundle(market.getVolatilitySurface().withSurface(bumpedVolUp), market.getDiscountCurve(),
market.getForwardCurve());
final double pvUp = derivative.accept(_pricer, bumpedMarket);
// shift DOWN
final InterpolatedDoublesSurface bumpedVolDown = volShifter.evaluate(blackSurf, maturity, strike, -shift);
bumpedMarket = new StaticReplicationDataBundle(market.getVolatilitySurface().withSurface(bumpedVolDown), market.getDiscountCurve(), market.getForwardCurve());
final double pvDown = derivative.accept(_pricer, bumpedMarket);
// Centered-difference result
return (pvUp - pvDown) / (2.0 * shift);