docs: @Override
  	public RandomVariable getValue(double evaluationTime, LIBORModelMonteCarloSimulationModel model) throws CalculationException {
  
  		double productToModelTimeOffset = 0;
  		try {
  			if(this.getReferenceDate() != null && model.getReferenceDate() != null) {
  				productToModelTimeOffset = FloatingpointDate.getFloatingPointDateFromDate(model.getReferenceDate(), this.getReferenceDate());
  			}
  		}
  		catch(UnsupportedOperationException e) {
  			// @TODO: Models that do not provide a reference date will become disfunctional in future releases.
  		};
  
  		if(evaluationTime >= productToModelTimeOffset + getPaymentDate()) {
  			return new RandomVariableFromDoubleArray(0.0);
  		}
  
  		// Get random variables
  		RandomVariable	notionalAtPeriodStart	= getNotional().getNotionalAtPeriodStart(this, model);
  		RandomVariable	numeraireAtEval			= model.getNumeraire(evaluationTime);
  		RandomVariable	numeraire				= model.getNumeraire(productToModelTimeOffset + getPaymentDate());
  		// @TODO: Add support for weighted Monte-Carlo.
  		//        RandomVariable	monteCarloProbabilities	= model.getMonteCarloWeights(getPaymentDate());
  
  		RandomVariable values;
  
  		// Calculate numeraire relative value of coupon flows
  		if(couponFlow) {
  			values = getCoupon(productToModelTimeOffset + getFixingDate(), model);
  			values = values.mult(notionalAtPeriodStart);
  			values = values.div(numeraire);
  			if(isExcludeAccruedInterest && evaluationTime >= productToModelTimeOffset + getPeriodStart() && evaluationTime < productToModelTimeOffset + getPeriodEnd()) {
  				double nonAccruedInterestRatio = (productToModelTimeOffset + getPeriodEnd() - evaluationTime) / (getPeriodEnd() - getPeriodStart());
  				values = values.mult(nonAccruedInterestRatio);
  			}
  		}
  		else {
  			values = new RandomVariableFromDoubleArray(0.0,0.0);
  		}
  
  		// Apply notional exchange
  		if(notionalFlow) {
  			RandomVariable	nationalAtPeriodEnd		= getNotional().getNotionalAtPeriodEnd(this, model);
  
  			if(getPeriodStart() > evaluationTime) {
  				RandomVariable	numeraireAtPeriodStart	= model.getNumeraire(getPeriodStart());
  				values = values.subRatio(notionalAtPeriodStart, numeraireAtPeriodStart);
  			}
  
  			if(getPeriodEnd() > evaluationTime) {
  				RandomVariable	numeraireAtPeriodEnd	= model.getNumeraire(getPeriodEnd());
  				values = values.addRatio(nationalAtPeriodEnd, numeraireAtPeriodEnd);
  			}
  		}
  
  		if(payer) {
  			values = values.mult(-1.0);
  		}
  
  		values = values.mult(numeraireAtEval);
  
  		// Return values
  		return values;
  	}