public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier): bool
    {
        $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName);

        if ($matchResult === false) {
            throw new Exception('Error in regular expression', 1168876915);
        } elseif ($matchResult !== 1) {
            return false;
        }

        switch ($this->methodVisibility) {
            case 'public':
                if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodPublic($methodDeclaringClassName, $methodName))) {
                    return false;
                }
                break;
            case 'protected':
                if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodProtected($methodDeclaringClassName, $methodName))) {
                    return false;
                }
                break;
        }

        $methodArguments = ($methodDeclaringClassName === null ? [] : $this->reflectionService->getMethodParameters($methodDeclaringClassName, $methodName));
        foreach (array_keys($this->methodArgumentConstraints) as $argumentName) {
            $objectAccess = explode('.', $argumentName, 2);
            $argumentName = $objectAccess[0];
            if (!array_key_exists($argumentName, $methodArguments)) {
                $this->logger->notice('The argument "' . $argumentName . '" declared in pointcut does not exist in method ' . $methodDeclaringClassName . '->' . $methodName);
                return false;
            }
        }
        return true;
    }