docs: @Override
  	public RandomVariableInterface[] getDrift(int timeIndex, RandomVariableInterface[] realizationAtTimeIndex, RandomVariableInterface[] realizationPredictor) {
  
  		double	time				= getTime(timeIndex);
  		double	timeStep			= getTimeDiscretization().getTimeStep(timeIndex);
  		double	timeNext			= getTime(timeIndex+1);
  
  		RandomVariableInterface		zero	= getProcess().getStochasticDriver().getRandomVariableForConstant(0.0);
  
  		// Allocate drift vector and initialize to zero (will be used to sum up drift components)
  		RandomVariableInterface[]	drift = new RandomVariableInterface[getNumberOfComponents()];
  		for(int componentIndex=0; componentIndex<getNumberOfComponents(); componentIndex++) {
  			drift[componentIndex] = null;
  		}
  
  		RandomVariableInterface[]	variances	= new RandomVariableInterface[getNumberOfComponents()];
  		for(int componentIndex=0; componentIndex<getNumberOfComponents(); componentIndex++) {
  			variances[componentIndex] = zero;
  		}
  
  		RandomVariableInterface[]	covarianceFactorSums	= new RandomVariableInterface[getNumberOfFactors()];
  		for(int factorIndex=0; factorIndex<getNumberOfFactors(); factorIndex++) {
  			covarianceFactorSums[factorIndex] = zero;
  		}
  
  		/*
  		 * Standard HJM drift part of log-forward-bond
  		 */
  		TimeDiscretizationInterface liborPeriodDiscretization = getLiborPeriodDiscretization(timeNext);
  		// Calculate drift for the component componentIndex (starting at firstLiborIndex, others are zero)
  		for(int componentIndex=0; componentIndex<liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex++) {
  			drift[componentIndex] = zero;
  
  			double						periodStart		= liborPeriodDiscretization.getTime(componentIndex);
  			double						periodLength	= liborPeriodDiscretization.getTimeStep(componentIndex);
  			double						periodEnd		= periodStart + periodLength;
  			double						tenorTime		= covarianceModel.getScaledTenorTime(periodStart, periodEnd);
  
  			// @todo Document that factorLoading componentIndexing is on time discretization of t+1 for interval (t,t+1)
  			RandomVariableInterface[]	factorLoading   	= getFactorLoading(timeIndex, componentIndex, realizationAtTimeIndex);
  			double weight = getWeightForTenorRefinement(periodStart,periodStart,periodStart,periodEnd);
  			for(int factorIndex=0; factorIndex<getNumberOfFactors(); factorIndex++) {
  				drift[componentIndex] = drift[componentIndex].addProduct(covarianceFactorSums[factorIndex].addProduct(factorLoading[factorIndex], weight),factorLoading[factorIndex]);
  				variances[componentIndex] = variances[componentIndex].addProduct(factorLoading[factorIndex], factorLoading[factorIndex]);
  				covarianceFactorSums[factorIndex] = covarianceFactorSums[factorIndex].addProduct(factorLoading[factorIndex],tenorTime);
  			}
  		}
  
  		/*
  		 * Change of tenor discretization - impact on log-forward-bond
  		 */
  		TimeDiscretizationInterface liborPeriodDiscretizationPrevious = getLiborPeriodDiscretization(time);
  		for(int componentIndex=0; componentIndex<liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex++) {
  			double						periodStart		= liborPeriodDiscretization.getTime(componentIndex);
  			double						periodLength	= liborPeriodDiscretization.getTimeStep(componentIndex);
  			double						periodEnd		= periodStart + periodLength;
  
  			double						periodStartPrevious		= liborPeriodDiscretizationPrevious.getTime(componentIndex);
  			double						periodLengthPrevious	= liborPeriodDiscretizationPrevious.getTimeStep(componentIndex);
  			double						periodEndPrevious		= periodStartPrevious + periodLengthPrevious;
  
  			if(periodStartPrevious == periodStart && periodEndPrevious == periodEnd) {
  				continue;
  			}
  
  			RandomVariableInterface		stateVariablePrevious	= getStateVariable(timeIndex, periodStartPrevious,	periodEndPrevious);
  			RandomVariableInterface		stateVariable			= getStateVariable(timeIndex, periodStart, 			periodEnd);
  
  			if(Double.isNaN(stateVariable.getAverage()) || Double.isNaN(stateVariablePrevious.getAverage())) {
  				throw new IllegalArgumentException();
  			}
  
  			// Shift in indexing and/or tenor refinement
  			drift[componentIndex] = drift[componentIndex].add(stateVariable.sub(stateVariablePrevious).div(timeStep));
  		}
  
  		/*
  		 * Integrated variance - drift part
  		 */
  		for(int componentIndex=0; componentIndex<liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex++) {
  			drift[getNumberOfLibors()+componentIndex] = variances[componentIndex];
  		}
  
  		/*
  		 * Change of tenor discretization - impact on integrated variance
  		 */
  		for(int componentIndex=0; componentIndex<liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex++) {
  			double						periodStart		= liborPeriodDiscretization.getTime(componentIndex);
  			double						periodLength	= liborPeriodDiscretization.getTimeStep(componentIndex);
  			double						periodEnd		= periodStart + periodLength;
  
  			double						periodStartPrevious		= liborPeriodDiscretizationPrevious.getTime(componentIndex);
  			double						periodLengthPrevious	= liborPeriodDiscretizationPrevious.getTimeStep(componentIndex);
  			double						periodEndPrevious		= periodStartPrevious + periodLengthPrevious;
  
  			if(periodStartPrevious == periodStart && periodEndPrevious == periodEnd) {
  				continue;
  			}
  
  			RandomVariableInterface		stateVariablePrevious	= getIntegratedVariance(timeIndex, periodStartPrevious, periodEndPrevious);
  			RandomVariableInterface		stateVariable			= getIntegratedVariance(timeIndex, periodStart, 		periodEnd);
  
  			if(Double.isNaN(stateVariable.getAverage()) || Double.isNaN(stateVariablePrevious.getAverage())) {
  				throw new IllegalArgumentException();
  			}
  
  			// Shift in indexing
  			drift[getNumberOfLibors()+componentIndex] = drift[getNumberOfLibors()+componentIndex].add(stateVariable.sub(stateVariablePrevious).div(timeStep));
  		}
  
  		return drift;
  	}