public function matches($selector, $strict = false)
    {
        if (!is_string($selector)) {
            throw new InvalidArgumentException(sprintf('%s expects parameter 1 to be string, %s given', __METHOD__, gettype($selector)));
        }

        if (!$this->node instanceof DOMElement) {
            return false;
        }

        if ($selector === '*') {
            return true;
        }

        if (!$strict) {
            $innerHtml = $this->html();
            $html = "<root>$innerHtml</root>";

            $selector = 'root > ' . trim($selector);

            $document = new Document();

            $document->loadHtml($html, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);

            return $document->has($selector);
        }

        $segments = Query::getSegments($selector);

        if (!array_key_exists('tag', $segments)) {
            throw new RuntimeException(sprintf('Tag name must be specified in %s', $selector));
        }

        if ($segments['tag'] !== $this->tag && $segments['tag'] !== '*') {
            return false;
        }

        $segments['id'] = array_key_exists('id', $segments) ? $segments['id'] : null;

        if ($segments['id'] !== $this->getAttribute('id')) {
            return false;
        }

        $classes = $this->hasAttribute('class') ? explode(' ', trim($this->getAttribute('class'))) : [];

        $segments['classes'] = array_key_exists('classes', $segments) ? $segments['classes'] : [];

        $diff1 = array_diff($segments['classes'], $classes);
        $diff2 = array_diff($classes, $segments['classes']);

        if (count($diff1) > 0 || count($diff2) > 0) {
            return false;
        }

        $attributes = $this->attributes();

        unset($attributes['id'], $attributes['class']);

        $segments['attributes'] = array_key_exists('attributes', $segments) ? $segments['attributes'] : [];

        $diff1 = array_diff_assoc($segments['attributes'], $attributes);
        $diff2 = array_diff_assoc($attributes, $segments['attributes']);

        // if the attributes are not equal
        if (count($diff1) > 0 || count($diff2) > 0) {
            return false;
        }

        return true;
    }