protected function byPredicate()
    {
        $fields = $this->fieldIdentifiers();
        if (empty($fields)) {
            throw new UnexpectedValueException(
                'Property is required.'
            );
        }

        $conditions = [];
        $value      = $this->value();
        $operator   = $this->operator();
        $function   = $this->func();
        foreach ($fields as $fieldName) {
            if ($function !== null) {
                $target = sprintf('%1$s(%2$s)', $function, $fieldName);
            } else {
                $target = $fieldName;
            }

            switch ($operator) {
                case 'FIND_IN_SET':
                    if ($value === null) {
                        throw new UnexpectedValueException(sprintf(
                            'Value is required on field "%s" for "%s"',
                            $target,
                            $operator
                        ));
                    }

                    if (is_array($value)) {
                        $value = implode(',', $value);
                    }

                    $conditions[] = sprintf('%2$s(\'%3$s\', %1$s)', $target, $operator, $value);
                    break;

                case '!':
                case 'NOT':
                    $conditions[] = sprintf('%2$s %1$s', $target, $operator);
                    break;

                case 'IS NULL':
                case 'IS TRUE':
                case 'IS FALSE':
                case 'IS UNKNOWN':
                case 'IS NOT NULL':
                case 'IS NOT TRUE':
                case 'IS NOT FALSE':
                case 'IS NOT UNKNOWN':
                    $conditions[] = sprintf('%1$s %2$s', $target, $operator);
                    break;

                case 'IN':
                case 'NOT IN':
                    if ($value === null) {
                        throw new UnexpectedValueException(sprintf(
                            'Value is required on field "%s" for "%s"',
                            $target,
                            $operator
                        ));
                    }

                    if (is_array($value)) {
                        $value = implode('\',\'', $value);
                    }

                    $conditions[] = sprintf('%1$s %2$s (\'%3$s\')', $target, $operator, $value);
                    break;

                default:
                    if ($value === null) {
                        throw new UnexpectedValueException(sprintf(
                            'Value is required on field "%s" for "%s"',
                            $target,
                            $operator
                        ));
                    }

                    $conditions[] = sprintf('%1$s %2$s \'%3$s\'', $target, $operator, $value);
                    break;
            }
        }

        return $this->compileConditions($conditions, 'OR');
    }