public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier): bool
    {
        if ($this->filters === null) {
            $this->buildPointcutFilters();
        }

        $matchingFilters = array_filter($this->filters, $this->getFilterEvaluator($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier));

        if ($matchingFilters === []) {
            return false;
        }

        /** @var PointcutFilterComposite $filter */
        foreach ($matchingFilters as $privilegeIdentifier => $filter) {
            $methodIdentifier = strtolower($className . '->' . $methodName);

            $hasRuntimeEvaluations = false;
            if ($filter->hasRuntimeEvaluationsDefinition() === true) {
                $hasRuntimeEvaluations = true;
                $this->runtimeExpressionEvaluator->addExpression($privilegeIdentifier, $filter->getRuntimeEvaluationsClosureCode());
            }

            $this->methodPermissions[$methodIdentifier][$privilegeIdentifier]['privilegeMatchesMethod'] = true;
            $this->methodPermissions[$methodIdentifier][$privilegeIdentifier]['hasRuntimeEvaluations'] = $hasRuntimeEvaluations;
        }

        return true;
    }