protected static function convertPseudo($pseudo, &$tagName, array $parameters = [])
    {
        switch ($pseudo) {
            case 'first-child':
                return 'position() = 1';
                break;
            case 'last-child':
                return 'position() = last()';
                break;
            case 'nth-child':
                $xpath = sprintf('(name()="%s") and (%s)', $tagName, self::convertNthExpression($parameters[0]));
                $tagName = '*';

                return $xpath;
                break;
            case 'contains':
                $string = trim($parameters[0], '\'"');

                if (count($parameters) === 1) {
                    return self::convertContains($string);
                }

                if ($parameters[1] !== 'true' && $parameters[1] !== 'false') {
                    throw new InvalidSelectorException(sprintf('Parameter 2 of "contains" pseudo-class must be equal true or false, "%s" given', $parameters[1]));
                }

                $caseSensitive = $parameters[1] === 'true';

                if (count($parameters) === 2) {
                    return self::convertContains($string, $caseSensitive);
                }

                if ($parameters[2] !== 'true' && $parameters[2] !== 'false') {
                    throw new InvalidSelectorException(sprintf('Parameter 3 of "contains" pseudo-class must be equal true or false, "%s" given', $parameters[2]));
                }

                $fullMatch = $parameters[2] === 'true';

                return self::convertContains($string, $caseSensitive, $fullMatch);
                break;
            case 'has':
                return self::cssToXpath($parameters[0], './/');
                break;
            case 'not':
                return sprintf('not(self::%s)', self::cssToXpath($parameters[0], ''));
                break;
            case 'nth-of-type':
                return self::convertNthExpression($parameters[0]);
                break;
            case 'empty':
                return 'count(descendant::*) = 0';
                break;
            case 'not-empty':
                return 'count(descendant::*) > 0';
                break;
        }

        throw new InvalidSelectorException(sprintf('Unknown pseudo-class "%s"', $pseudo));
    }