protected function whereArgumentsToCriterion(
        array $arguments,
        string $appendRule = 'AND',
        bool $valueIsColumn = false
    ): Criterion {
        switch ($argumentsCount = count($arguments)) {
            case 0:
                return $this->handleException(new InvalidArgumentException('Too few arguments'));
            case 1:
                $argument = $arguments[0];

                if ($argument instanceof \Closure) {
                    $groupQuery = $this->resolveCriteriaGroupClosure($argument);
                    return new CriteriaCriterion($groupQuery->where, false, $appendRule);
                }

                if (is_array($argument)) {
                    $criteria = [];
                    foreach ($argument as $criterionData) {
                        $criteria[] = $this->whereArgumentsToCriterion($criterionData, 'AND', $valueIsColumn);
                    }
                    return new CriteriaCriterion($criteria, false, $appendRule);
                }

                if ($argument instanceof StatementInterface) {
                    return new RawCriterion($argument, $appendRule);
                }

                return $this->handleException(InvalidArgumentException::create(
                    'The argument',
                    $argument,
                    ['Closure', 'array', StatementInterface::class]
                ));
            case 2:
            case 3:
                if ($argumentsCount === 2) {
                    list($column, $value) = $arguments;
                    $rule = '=';
                } else {
                    list($column, $rule, $value) = $arguments;
                    if (!is_string($rule)) {
                        return $this->handleException(InvalidArgumentException::create('Argument $rule', $rule, ['string']));
                    }
                }

                if ($valueIsColumn) {
                    $column1 = $this->checkStringValue('Argument $column1', $column);
                    $column2 = $this->checkStringValue('Argument $column2', $value);
                    return new ColumnsCriterion($column1, $rule, $column2, $appendRule);
                } else {
                    $column = $this->checkStringValue('Argument $column', $column);
                    $value = $this->checkScalarOrNullValue('Argument $value', $value);
                    return new ValueCriterion($column, $rule, $value, $appendRule);
                }
            default:
                return $this->handleException(new InvalidArgumentException('Too many arguments'));
        }
    }