docs: @Override
  	public RandomVariableInterface getValue(double evaluationTime, LIBORModelMonteCarloSimulationInterface model) throws CalculationException {
  		/*
  		 * Calculate value of the swap at exercise date on each path (beware of perfect foresight - all rates are simulationTime=exerciseDate)
  		 */
  		RandomVariableInterface valueOfSwapAtExerciseDate	= model.getRandomVariableForConstant(/*fixingDates[fixingDates.length-1],*/0.0);
  
  		// Calculate the value of the swap by working backward through all periods
  		for(int period=fixingDates.length-1; period>=0; period--)
  		{
  			double fixingDate	= fixingDates[period];
  			double paymentDate	= paymentDates[period];
  			double swaprate		= swaprates[period];
  
  			if(paymentDate <= evaluationTime) {
  				break;
  			}
  
  			double periodLength	= periodLengths != null ? periodLengths[period] : paymentDate - fixingDate;
  
  			// Get random variables - note that this is the rate at simulation time = exerciseDate
  			RandomVariableInterface libor	= model.getLIBOR(exerciseDate, fixingDate, paymentDate);
  
  			// Calculate payoff
  			RandomVariableInterface payoff = libor.sub(swaprate).mult(periodLength);
  
  			// Calculated the adjustment for the discounting curve, assuming a deterministic basis
  			// @TODO: Need to check if the model fulfills the assumptions (all models implementing the interface currently do so).
  			double discountingDate = Math.max(fixingDate,exerciseDate);
  			double discountingAdjustment = 1.0;
  			if(model.getModel() != null && model.getModel().getDiscountCurve() != null) {
  				AnalyticModelInterface analyticModel = model.getModel().getAnalyticModel();
  				DiscountCurveInterface discountCurve = model.getModel().getDiscountCurve();
  				ForwardCurveInterface forwardCurve = model.getModel().getForwardRateCurve();
  				DiscountCurveInterface discountCurveFromForwardCurve = new DiscountCurveFromForwardCurve(forwardCurve);
  
  				double forwardBondOnForwardCurve = discountCurveFromForwardCurve.getDiscountFactor(analyticModel, discountingDate) / discountCurveFromForwardCurve.getDiscountFactor(analyticModel, paymentDate);
  				double forwardBondOnDiscountCurve = discountCurve.getDiscountFactor(analyticModel, discountingDate) / discountCurve.getDiscountFactor(analyticModel, paymentDate);
  				discountingAdjustment = forwardBondOnForwardCurve / forwardBondOnDiscountCurve;
  			}
  
  			// Add payment received at end of period
  			valueOfSwapAtExerciseDate = valueOfSwapAtExerciseDate.add(payoff);
  
  			// Discount back to beginning of period
  			valueOfSwapAtExerciseDate = valueOfSwapAtExerciseDate.discount(libor, paymentDate - discountingDate).mult(discountingAdjustment);
  		}
  
  		/*
  		 * Calculate swaption value
  		 */
  		RandomVariableInterface values = valueOfSwapAtExerciseDate.floor(0.0);
  
  		RandomVariableInterface	numeraire				= model.getNumeraire(exerciseDate);
  		RandomVariableInterface	monteCarloProbabilities	= model.getMonteCarloWeights(exerciseDate);
  		values = values.div(numeraire).mult(monteCarloProbabilities);
  
  		RandomVariableInterface	numeraireAtZero					= model.getNumeraire(evaluationTime);
  		RandomVariableInterface	monteCarloProbabilitiesAtZero	= model.getMonteCarloWeights(evaluationTime);
  		values = values.mult(numeraireAtZero).div(monteCarloProbabilitiesAtZero);
  
  		return values;
  	}