def _recommend(self, client_data, limit, extra_data={}):
        self.logger.info("Ensemble recommend invoked")
        preinstalled_addon_ids = client_data.get("installed_addons", [])
        extended_limit = limit + len(preinstalled_addon_ids)
        flattened_results = []
        ensemble_weights = self._weight_cache.getWeights()
        for rkey in self.RECOMMENDER_KEYS:
            recommender = self._recommender_map[rkey]
            if recommender.can_recommend(client_data):
                raw_results = recommender.recommend(
                    client_data, extended_limit, extra_data
                )
                reweighted_results = []
                for guid, weight in raw_results:
                    item = (guid, weight * ensemble_weights[rkey])
                    reweighted_results.append(item)
                flattened_results.extend(reweighted_results)
        flattened_results.sort(key=lambda item: item[0])
        guid_grouper = itertools.groupby(flattened_results, lambda item: item[0])
        ensemble_suggestions = []
        for (guid, guid_group) in guid_grouper:
            weight_sum = sum([v for (g, v) in guid_group])
            item = (guid, weight_sum)
            ensemble_suggestions.append(item)
        ensemble_suggestions.sort(key=lambda x: -x[1])
        filtered_ensemble_suggestions = [
            (guid, weight)
            for (guid, weight) in ensemble_suggestions
            if guid not in preinstalled_addon_ids
        ]
        results = filtered_ensemble_suggestions[:limit]
        log_data = (
            client_data["client_id"],
            str(ensemble_weights),
            str([r[0] for r in results]),
        )
        self.logger.info(
            "client_id: [%s], ensemble_weight: [%s], guids: [%s]" % log_data
        )
        return results