def evaluate(self, index):
    """ Given a custom attribute audience condition and user attributes, evaluate the
        condition against the attributes.

    Args:
      index: Index of the condition to be evaluated.

    Returns:
      Boolean:
        - True if the user attributes match the given condition.
        - False if the user attributes don't match the given condition.
      None: if the user attributes and condition can't be evaluated.
    """

    if self.condition_data[index][2] != self.CUSTOM_ATTRIBUTE_CONDITION_TYPE:
      self.logger.warning(audience_logs.UNKNOWN_CONDITION_TYPE.format(self._get_condition_json(index)))
      return None

    condition_match = self.condition_data[index][3]
    if condition_match is None:
      condition_match = ConditionMatchTypes.EXACT

    if condition_match not in self.EVALUATORS_BY_MATCH_TYPE:
      self.logger.warning(audience_logs.UNKNOWN_MATCH_TYPE.format(self._get_condition_json(index)))
      return None

    if condition_match != ConditionMatchTypes.EXISTS:
      attribute_key = self.condition_data[index][0]
      if attribute_key not in self.attributes:
        self.logger.debug(audience_logs.MISSING_ATTRIBUTE_VALUE.format(self._get_condition_json(index), attribute_key))
        return None

      if self.attributes.get(attribute_key) is None:
        self.logger.debug(audience_logs.NULL_ATTRIBUTE_VALUE.format(self._get_condition_json(index), attribute_key))
        return None

    return self.EVALUATORS_BY_MATCH_TYPE[condition_match](self, index)
Given a custom attribute audience condition and user attributes, evaluate the
        condition against the attributes.

    Args:
      index: Index of the condition to be evaluated.

    Returns:
      Boolean:
        - True if the user attributes match the given condition.
        - False if the user attributes don't match the given condition.
      None: if the user attributes and condition can't be evaluated.