CallSpecifiedMultiProduct::CallSpecifiedMultiProduct(
                         const Clone<MarketModelMultiProduct>& underlying,
                         const Clone<ExerciseStrategy<CurveState> >& strategy,
                         const Clone<MarketModelMultiProduct>& rebate)
                    : underlying_(underlying), 
                    strategy_(strategy), 
                    rebate_(rebate),
                    callable_(true) 
    {

        Size products = underlying_->numberOfProducts();
        EvolutionDescription d1 = underlying->evolution();
        const std::vector<Time>& rateTimes1 = d1.rateTimes();
        const std::vector<Time>& evolutionTimes1 = d1.evolutionTimes();
        const std::vector<Time>& exerciseTimes = strategy->exerciseTimes();

        if (!rebate_.empty()) 
        {
            EvolutionDescription d2 = rebate_->evolution();
            const std::vector<Time>& rateTimes2 = d2.rateTimes();
            QL_REQUIRE(rateTimes1.size() == rateTimes2.size() &&
                       std::equal(rateTimes1.begin(), rateTimes1.end(),
                                  rateTimes2.begin()),
                       "incompatible rate times");
        } 
        else
        {
            EvolutionDescription description(rateTimes1, exerciseTimes);
            Matrix amounts(products, exerciseTimes.size(), 0.0);

            rebate_ = MarketModelCashRebate(description, exerciseTimes,
                                            amounts, products);
        }

        std::vector<Time> mergedEvolutionTimes;
        std::vector<std::vector<Time> > allEvolutionTimes(4);
        allEvolutionTimes[0] = evolutionTimes1;
        allEvolutionTimes[1] = exerciseTimes;
        allEvolutionTimes[2] = rebate_->evolution().evolutionTimes();
        allEvolutionTimes[3] = strategy->relevantTimes();

        mergeTimes(allEvolutionTimes,
                                    mergedEvolutionTimes,
                                    isPresent_);

        // TODO: add relevant rates
        evolution_ = EvolutionDescription(rateTimes1, mergedEvolutionTimes);

        cashFlowTimes_ = underlying_->possibleCashFlowTimes();
        rebateOffset_ = cashFlowTimes_.size();
        const std::vector<Time> rebateTimes = rebate_->possibleCashFlowTimes();
        cashFlowTimes_.insert(cashFlowTimes_.end(),
                                                           rebateTimes.begin(), rebateTimes.end());

        dummyCashFlowsThisStep_ = std::vector<Size>(products, 0);
        Size n = rebate_->maxNumberOfCashFlowsPerProductPerStep();
        dummyCashFlowsGenerated_ =
            std::vector<std::vector<CashFlow> >(products,
                                                std::vector<CashFlow>(n));
    }