    public boolean processImpression(User user, Query query, Auction auction) {
        fireQueryIssued(query);
        boolean converted = false;
        boolean clicking = true;
        double continuationProbability = 0.0;
        int queryIndex = userClickModel.queryIndex(query);
        if (queryIndex < 0) {
            log.warning(String.format("Query: %s does not have a click model.",
                    query));
        } else {
            continuationProbability = userClickModel
                    .getContinuationProbability(queryIndex);
        }
        Ranking ranking = auction.getRanking();
        Pricing pricing = auction.getPricing();
        for (int i = 0; i < ranking.size(); i++) {
            AdLink ad = ranking.get(i);
            boolean isPromoted = ranking.isPromoted(i);
            fireAdViewed(query, ad, i + 1, isPromoted);
            if (clicking) {
                AdvertiserInfo info = advertiserInfo.get(ad.getAdvertiser());
                double promotionEffect = ranking.isPromoted(i) ? slotInfo
                        .getPromotedSlotBonus() : 0.0;
                double clickProbability = calculateClickProbability(user, ad.getAd(), info.getTargetEffect(),
                        promotionEffect, findAdvertiserEffect(query, ad, userClickModel));
                if (random.nextDouble() <= clickProbability) {
                    fireAdClicked(query, ad, i + 1, pricing.getPrice(ad));
                    double conversionProbability = calculateConversionProbability( user, query, info,
                            recentConversionsTracker.getRecentConversions(ad.getAdvertiser()));
                    if(user.isTransacting()){
                        if (random.nextDouble() <= conversionProbability) {
                            double salesProfit = catalog.getSalesProfit(user
                                    .getProduct());
                            fireAdConverted(query, ad, i + 1, modifySalesProfitForManufacturerSpecialty(user,
                                            info.getManufacturerSpecialty(), info.getManufacturerBonus(), salesProfit));
                            converted = true;
                            clicking = false;
                        }
                    }
                }
            }
            if (random.nextDouble() > continuationProbability) {
                clicking = false;
            }
        }
        return converted;
    }

    public boolean processImpression(User user, Query query, Auction auction) {
        fireQueryIssued(query);
        boolean converted = false;
        boolean clicking = true;
        double continuationProbability = 0.0;
        int queryIndex = userClickModel.queryIndex(query);
        if (queryIndex < 0) {
            log.warning(String.format("Query: %s does not have a click model.",
                    query));
        } else {
            continuationProbability = userClickModel
                    .getContinuationProbability(queryIndex);
        }
        Ranking ranking = auction.getRanking();
        Pricing pricing = auction.getPricing();
        for (int i = 0; i < ranking.size(); i++) {
            AdLink ad = ranking.get(i);
            boolean isPromoted = ranking.isPromoted(i);
            fireAdViewed(query, ad, i + 1, isPromoted);
            if (clicking) {
                AdvertiserInfo info = advertiserInfo.get(ad.getAdvertiser());
                double promotionEffect = ranking.isPromoted(i) ? slotInfo
                        .getPromotedSlotBonus() : 0.0;
                double clickProbability = calculateClickProbability(user, ad.getAd(), info.getTargetEffect(),
                        promotionEffect, findAdvertiserEffect(query, ad, userClickModel));
                if (random.nextDouble() <= clickProbability) {
                    fireAdClicked(query, ad, i + 1, pricing.getPrice(ad));
                    double conversionProbability = calculateConversionProbability( user, query, info,
                            recentConversionsTracker.getRecentConversions(ad.getAdvertiser()));
                        if (random.nextDouble() <= conversionProbability) {
                            double salesProfit = catalog.getSalesProfit(user
                                    .getProduct());
                            fireAdConverted(query, ad, i + 1, modifySalesProfitForManufacturerSpecialty(user,
                                            info.getManufacturerSpecialty(), info.getManufacturerBonus(), salesProfit));
                            converted = true;
                            clicking = false;
                        }
                }
            }
            if (random.nextDouble() > continuationProbability) {
                clicking = false;
            }
        }
        return converted;
    }
