QL.require(payoff!=null , "non-plain payoff given"); // QA:[RG]::verified // TODO: message
final double maturity = rfdc.yearFraction(referenceDate, maturityDate);
final StochasticProcess1D bs = new GeneralizedBlackScholesProcess(process.stateVariable(), flatDividends, flatRiskFree, flatVol);
final TimeGrid grid = new TimeGrid(maturity, timeSteps);
final Tree tree = (Tree)getTreeInstance(bs, maturity, timeSteps, payoff.strike());
final BlackScholesDividendLattice<Tree> lattice = new BlackScholesDividendLattice<Tree>(tree, rRate, maturity, timeSteps,
rfdc, grid, referenceDate, a.cashFlow);
final DiscretizedVanillaOption option = new DiscretizedVanillaOption(a, process, grid);
option.initialize(lattice, maturity);
// Partial derivatives calculated from various points in the binomial tree (Odegaard)
// Rollback to third-last step, and get underlying price (s2) & option values (p2) at this point
option.rollback(grid.at(2));
final Array va2 = option.values();
QL.require(va2.size() == 3 , "expect 3 nodes in grid at second step"); // QA:[RG]::verified // TODO: message
final double p2h = va2.get(2); // high-price
final double s2 = lattice.underlying(2, 2); // high price
// Rollback to second-last step, and get option value (p1) at this point
option.rollback(grid.at(1));
final Array va = option.values();
QL.require(va.size() == 2, "expect 2 nodes in grid at first step"); // QA:[RG]::verified // TODO: message
final double p1 = va.get(1);
// Finally, rollback to t=0