/// <summary>
        /// Aggregate the valuation profile onto a set of result curves to support result partitioning.
        /// </summary>
        protected override void ProcessResults(ValuationResults valResults, DealPartitionAssociations assoc, PriceFactorList factors, BaseTimeGrid baseTimes, ValuationOptions options, int partition)
        {
            var pvProfiles          = valResults.Results <PVProfiles>();
            var addOnProfiles       = valResults.Results <AddOnProfiles>();
            var positiveMtmProfiles = valResults.Results <PositiveMtmProfiles>();

            Debug.Assert(addOnProfiles != null, "No Add-On profiles. Cannot proceed with valuation.");
            Debug.Assert(positiveMtmProfiles != null, "No Positive mtM profiles. Cannot proceed with valuation.");

            fT = Deal.ValuationGrid(factors, baseTimes, Deal.EndDate());
            var tgi = new TimeGridIterator(fT);

            var nettedExposure     = new PVProfiles(factors.NumScenarios);
            var collateralExposure = new PVProfiles(factors.NumScenarios);

            var addOnsProfile  = new PVProfiles(factors.NumScenarios);
            var mtmTermProfile = new PVProfiles(factors.NumScenarios);

            DealBaselNettingCollateralSet nettingSetDeal = Deal as DealBaselNettingCollateralSet;

            bool collateralised = nettingSetDeal.Collateralised == YesNo.Yes;

            using (var cache = Vector.Cache(factors.NumScenarios))
            {
                Vector sumMtm         = cache.Get();
                Vector sumPositiveMtm = cache.Get();
                Vector addOns         = cache.Get();
                Vector netGrossRatio  = cache.Get();
                Vector value          = cache.Get();
                Vector term1          = cache.Get();
                Vector term2          = cache.Get();

                // Collateral related vectors.
                Vector mtmTermStart = cache.Get();
                Vector addOnHp      = cache.Get();

                // Loop to get the netting set exposure.
                while (tgi.Next())
                {
                    sumMtm.Clear();
                    sumPositiveMtm.Clear();
                    addOns.Clear();
                    value.Clear();

                    double date = tgi.Date;

                    // For MtM Plus Add-On deals PV profiles represents the sum of the MtM profile and Add-On profile.
                    // Subtract the Add-On profile to recover the MtM profile before flooring.
                    sumMtm.Assign(VectorMath.Max(pvProfiles[date] - addOnProfiles[date], 0.0));

                    addOns.Assign(addOnProfiles[date]);
                    sumPositiveMtm.Assign(positiveMtmProfiles[date]);

                    netGrossRatio.AssignConditional(sumPositiveMtm > 0, sumMtm / sumPositiveMtm, 0.0);

                    netGrossRatio.MultiplyBy(this.fNetGrossRatioCorrelation);
                    netGrossRatio.Add(1 - this.fNetGrossRatioCorrelation);

                    term2.AssignProduct(addOns, netGrossRatio);

                    term1.Assign(VectorMath.Max(sumMtm, 0.0));

                    value.AssignSum(term1, term2);

                    nettedExposure.AppendVector(date, value);

                    if (collateralised)
                    {
                        mtmTermProfile.AppendVector(date, term1);
                        addOnsProfile.AppendVector(date, term2);
                    }
                }

                nettedExposure.Complete(this.fT);

                var exposureResults = valResults.Results <Exposure>();
                if (exposureResults != null)
                {
                    exposureResults.Assign(nettedExposure);
                }

                // Collateral cases.
                if (collateralised)
                {
                    mtmTermProfile.Complete(this.fT);
                    addOnsProfile.Complete(this.fT);

                    double date = factors.BaseDate;

                    mtmTermProfile.GetValue(mtmTermStart, date);
                    addOnsProfile.GetValue(addOnHp, date + nettingSetDeal.Holding_Period);

                    // Assume we have post haircut collateral.
                    double collateral = nettingSetDeal.Balance;
                    double threshold  = nettingSetDeal.Threshold;

                    tgi.Reset();

                    // Loop to get the netting set exposure.
                    while (tgi.Next())
                    {
                        bool inHoldingPeriod = tgi.T < CalcUtils.DaysToYears(nettingSetDeal.Holding_Period);

                        CollateralBasel3(mtmTermStart, collateral, addOnHp, threshold, inHoldingPeriod, tgi.Date,
                                         nettedExposure,
                                         collateralExposure);
                    }

                    collateralExposure.Complete(this.fT);

                    if (exposureResults != null)
                    {
                        exposureResults.Assign(collateralExposure);
                    }
                }
            }

            if (options.PartitionCollateralMode != PartitionCollateralMode.Suppress_Collateral_And_Flooring || partition < options.NumTotalPartitions)
            {
                valResults.FloorResult(assoc.AggregationMode, options);
            }

            CollateralPlugIn.CollateralBalancesContainer coProfiles = valResults.Results <CollateralPlugIn.CollateralBalancesContainer>();

            // Store collateral information according to diagnostic collection rules.
            if (coProfiles != null)
            {
                coProfiles.StoreInformation(this);
            }
        }