def METHOD_NAME(self, feature_flag, matching_key, bucketing_key, attributes=None):
    """
    Evaluate the feature considering the conditions.
    If there is a match, it will return the condition and the label.
    Otherwise, it will return (None, None)
    :param feature_flag: The feature flag for which to get the treatment
    :type feature_flag: Split
    :param matching_key: The key for which to get the treatment
    :type key: str
    :param bucketing_key: The key for which to get the treatment
    :type key: str
    :param attributes: An optional dictionary of attributes
    :type attributes: dict
    :return: The resulting treatment and label
    :rtype: tuple
    """
    if bucketing_key is None:
        bucketing_key = matching_key
    roll_out = False
    context = {
        'segment_storage': self._segment_storage,
        'evaluator': self,
        'bucketing_key': bucketing_key
    }
    for condition in feature_flag.conditions:
        if (not roll_out and
                condition.condition_type == ConditionType.ROLLOUT):
            if feature_flag.traffic_allocation < 100:
                bucket = self._splitter.get_bucket(
                    bucketing_key,
                    feature_flag.traffic_allocation_seed,
                    feature_flag.algo
                )
                if bucket > feature_flag.traffic_allocation:
                    return feature_flag.default_treatment, Label.NOT_IN_SPLIT
            roll_out = True
        condition_matches = condition.matches(
            matching_key,
            attributes=attributes,
            context=context
        )
        if condition_matches:
            return self._splitter.get_treatment(
                bucketing_key,
                feature_flag.seed,
                condition.partitions,
                feature_flag.algo
            ), condition.label
    # No condition matches
    return None, None