docs: @Override
  	public RandomVariableInterface getValue(double evaluationTime, LIBORModelMonteCarloSimulationInterface model) throws CalculationException {
  
  		// After the last period the product has value zero: Initialize values to zero.
  		RandomVariableInterface values = new RandomVariable(fixingDates[fixingDates.length-1], 0.0);
  
  		// Loop backward over the swap periods
  		for(int period=fixingDates.length-1; period>=0; period--)
  		{
  			double fixingDate	= fixingDates[period];
  			double periodLength	= periodLengths[period];
  			double paymentDate	= paymentDates[period];
  			double notional		= periodNotionals[period];
  			double swaprate		= swaprates[period];
  
  			// Get random variables - note that this is the rate at simulation time = exerciseDate
  			RandomVariableInterface	libor					= model.getLIBOR(fixingDate, fixingDate, fixingDate+periodLength);
  			RandomVariableInterface	numeraire               = model.getNumeraire(paymentDate);
  			RandomVariableInterface	monteCarloProbabilities = model.getMonteCarloWeights(paymentDate);
  
  			// foreach(path) values[path] += notional * (libor.get(path) - swaprate) * periodLength / numeraire.get(path) * monteCarloProbabilities.get(path);
  			RandomVariableInterface payoff = libor.sub(swaprate).mult(periodLength).mult(notional);
  
  			// Apply discounting and Monte-Carlo probabilities
  			payoff = payoff.div(numeraire).mult(monteCarloProbabilities);
  
  			values = values.add(payoff);
  
  			if(isPeriodStartDateExerciseDate[period]) {
  				// Remove foresight through condition expectation
  				ConditionalExpectationEstimatorInterface condExpEstimator = getConditionalExpectationEstimator(period, model);
  
  				// Calculate conditional expectation. Note that no discounting (numeraire division) is required!
  				RandomVariableInterface valueIfExcercised         = condExpEstimator.getConditionalExpectation(values);
  
  				// Apply the exercise criteria
  				// foreach(path) if(valueIfExcercided.get(path) < 0.0) values[path] = 0.0;
  				values = values.barrier(valueIfExcercised, values, 0.0);
  			}
  		}
  
  		RandomVariableInterface	numeraireAtZero						= model.getNumeraire(evaluationTime);
  		RandomVariableInterface	monteCarloProbabilitiesAtZero		= model.getMonteCarloWeights(evaluationTime);
  		values = values.mult(numeraireAtZero).div(monteCarloProbabilitiesAtZero);
  
  		return values;
  	}