docs: @Override
  	public RandomVariable[] getDrift(int timeIndex, RandomVariable[] realizationAtTimeIndex, RandomVariable[] realizationPredictor) {
  		double	time				= getTime(timeIndex);
  		int		firstLiborIndex		= this.getLiborPeriodIndex(time)+1;
  		if(firstLiborIndex<0) {
  			firstLiborIndex = -firstLiborIndex-1 + 1;
  		}
  
  		// Allocate drift vector and initialize to zero (will be used to sum up drift components)
  		RandomVariable[]	drift = new RandomVariable[getNumberOfComponents()];
  		RandomVariable[][]	covarianceFactorSums	= new RandomVariable[getNumberOfComponents()][getNumberOfFactors()];
  		for(int componentIndex=firstLiborIndex; componentIndex<getNumberOfComponents(); componentIndex++) {
  			drift[componentIndex] = new RandomVariableFromDoubleArray(0.0);
  		}
  
  		// Calculate drift for the component componentIndex (starting at firstLiborIndex, others are zero)
  		for(int componentIndex=firstLiborIndex; componentIndex<getNumberOfComponents(); componentIndex++) {
  			double						periodLength		= liborPeriodDiscretization.getTimeStep(componentIndex);
  			RandomVariable libor = realizationAtTimeIndex[componentIndex];
  			RandomVariable oneStepMeasureTransform = libor.discount(libor, periodLength).mult(periodLength);
  
  			//oneStepMeasureTransform = oneStepMeasureTransform.mult(libor);
  
  			RandomVariable[]	factorLoading   	= getFactorLoading(timeIndex, componentIndex, realizationAtTimeIndex);
  			RandomVariable[]   covarianceFactors   = new RandomVariable[getNumberOfFactors()];
  			for(int factorIndex=0; factorIndex<getNumberOfFactors(); factorIndex++) {
  				covarianceFactors[factorIndex] = factorLoading[factorIndex].mult(oneStepMeasureTransform);
  				covarianceFactorSums[componentIndex][factorIndex] = covarianceFactors[factorIndex];
  				if(componentIndex > firstLiborIndex) {
  					covarianceFactorSums[componentIndex][factorIndex] = covarianceFactorSums[componentIndex][factorIndex].add(covarianceFactorSums[componentIndex-1][factorIndex]);
  				}
  			}
  			for(int factorIndex=0; factorIndex<getNumberOfFactors(); factorIndex++) {
  				drift[componentIndex] = drift[componentIndex].addProduct(covarianceFactorSums[componentIndex][factorIndex], factorLoading[factorIndex]);
  			}
  		}
  
  		// Above is the drift for the spot measure: a simple conversion makes it the drift of the terminal measure.
  		if(measure == Measure.TERMINAL) {
  			for(int componentIndex=firstLiborIndex; componentIndex<getNumberOfComponents(); componentIndex++) {
  				drift[componentIndex] = drift[componentIndex].sub(drift[getNumberOfComponents()-1]);
  			}
  		}
  
  		// Drift adjustment for log-coordinate in each component
  		for(int componentIndex=firstLiborIndex; componentIndex<getNumberOfComponents(); componentIndex++) {
  			RandomVariable		variance		= covarianceModel.getCovariance(timeIndex, componentIndex, componentIndex, realizationAtTimeIndex);
  			drift[componentIndex] = drift[componentIndex].addProduct(variance, -0.5);
  		}
  
  		return drift;
  	}