protected function joinArgumentsToJoinObject(string $type, $table, array $criterion = []): Join
    {
        if (is_array($table)) {
            $tableName = $table[0] ?? null;
            $tableAlias = $table[1] ?? null;
        } else {
            $tableName = $table;
            $tableAlias = null;
        }

        $tableName = $this->checkStringValue('Argument $tableName', $tableName);
        if ($tableAlias !== null && !is_string($tableAlias)) {
            return $this->handleException(InvalidArgumentException::create(
                'Argument $tableAlias',
                $tableAlias,
                ['string', 'null']
            ));
        }

        if ($criterion) {
            $criterion = $this->whereArgumentsToCriterion($criterion, 'AND', true);
            $criteria = ($criterion instanceof CriteriaCriterion && !$criterion->not)
                ? $criterion->criteria
                : [$criterion];
        } else {
            $criteria = [];
        }

        return new Join($type, $tableName, $tableAlias, $criteria);
    }