### Question:
EuropeanVanillaOptionFunction implements OptionFunction, ImmutableBean, Serializable { public static EuropeanVanillaOptionFunction of(double strike, double timeToExpiry, PutCall putCall, int numberOfSteps) { double sign = putCall.isCall() ? 1d : -1d; ArgChecker.isTrue(numberOfSteps > 0, "the number of steps should be positive"); return new EuropeanVanillaOptionFunction(strike, timeToExpiry, sign, numberOfSteps); } private  EuropeanVanillaOptionFunction(
      double strike,
      double timeToExpiry,
      double sign,
      int numberOfSteps); static EuropeanVanillaOptionFunction of(double strike, double timeToExpiry, PutCall putCall, int numberOfSteps); @Override DoubleArray getPayoffAtExpiryTrinomial(DoubleArray stateValue); static EuropeanVanillaOptionFunction.Meta meta(); @Override EuropeanVanillaOptionFunction.Meta metaBean(); double getStrike(); @Override double getTimeToExpiry(); double getSign(); @Override int getNumberOfSteps(); @Override boolean equals(Object obj); @Override int hashCode(); @Override String toString();  }### Answer:
@Test public void test_trinomialTree() { int nSteps = 135; LatticeSpecification[] lattices = new LatticeSpecification[] {new CoxRossRubinsteinLatticeSpecification(), new TrigeorgisLatticeSpecification() }; double tol = 5.0e-3; for (boolean isCall : new boolean[] {true, false }) { for (double strike : STRIKES) { for (double interest : INTERESTS) { for (double vol : VOLS) { for (double dividend : DIVIDENDS) { OptionFunction function = EuropeanVanillaOptionFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps); double exact = BlackScholesFormulaRepository.price(SPOT, strike, TIME, vol, interest, interest - dividend, isCall); for (LatticeSpecification lattice : lattices) { double computed = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend); assertThat(computed).isCloseTo(exact, offset(Math.max(exact, 1d) * tol)); } } } } } } }