docs: @Override
  	public RandomVariableInterface getValue(double evaluationTime, LIBORModelMonteCarloSimulationInterface model) throws CalculationException {
  		// This is on the LIBOR discretization
  		double	paymentDate	= maturity+periodLength;
  
  		// Get random variables
  		RandomVariableInterface	libor					= model.getLIBOR(maturity, maturity, maturity+periodLength);
  		RandomVariableInterface	numeraire				= model.getNumeraire(paymentDate);
  		RandomVariableInterface	monteCarloProbabilities	= model.getMonteCarloWeights(paymentDate);
  
  		/*
  		 * Calculate the payoff, which is
  		 *    max(L-K,0) * periodLength         for caplet or
  		 *   -min(L-K,0) * periodLength         for floorlet.
  		 */
  		RandomVariableInterface values = libor;
  		if(!isFloorlet) {
  			values = values.sub(strike).floor(0.0).mult(daycountFraction);
  		} else {
  			values = values.sub(strike).cap(0.0).mult(-1.0 * daycountFraction);
  		}
  
  		values = values.div(numeraire).mult(monteCarloProbabilities);
  
  		RandomVariableInterface	numeraireAtValuationTime				= model.getNumeraire(evaluationTime);
  		RandomVariableInterface	monteCarloProbabilitiesAtValuationTime	= model.getMonteCarloWeights(evaluationTime);
  		values = values.mult(numeraireAtValuationTime).div(monteCarloProbabilitiesAtValuationTime);
  
  		if(valueUnit == ValueUnit.VALUE) {
  			return values;
  		}
  		else if(valueUnit == ValueUnit.LOGNORMALVOLATILITY || valueUnit == ValueUnit.VOLATILITY) {
  			/*
  			 * This calculation makes sense only if the value is an unconditional one.
  			 */
  			double forward = libor.div(numeraire).mult(monteCarloProbabilities).mult(numeraireAtValuationTime).div(monteCarloProbabilitiesAtValuationTime).getAverage();
  			double optionMaturity = maturity-evaluationTime;
  			double optionStrike = strike;
  			double payoffUnit = daycountFraction;
  			return model.getRandomVariableForConstant(AnalyticFormulas.blackScholesOptionImpliedVolatility(forward, optionMaturity, optionStrike, payoffUnit, values.getAverage()));
  		}
  		else if(valueUnit == ValueUnit.NORMALVOLATILITY) {
  			/*
  			 * This calculation makes sense only if the value is an unconditional one.
  			 */
  			double forward = libor.div(numeraire).mult(monteCarloProbabilities).mult(numeraireAtValuationTime).div(monteCarloProbabilitiesAtValuationTime).getAverage();
  			double optionMaturity = maturity-evaluationTime;
  			double optionStrike = strike;
  			double payoffUnit = daycountFraction;
  			return model.getRandomVariableForConstant(AnalyticFormulas.bachelierOptionImpliedVolatility(forward, optionMaturity, optionStrike, payoffUnit, values.getAverage()));
  		}
  		else {
  			throw new IllegalArgumentException("Value unit " + valueUnit + " unsupported.");
  		}
  	}