/**
  * Checks if the specified class and method matches against the filter, i.e. if there is a policy entry to intercept this method.
  * This method also creates a cache entry for every method, to cache the associated roles and privileges.
  *
  * @param string $className Name of the class to check the name of
  * @param string $methodName Name of the method to check the name of
  * @param string $methodDeclaringClassName Name of the class the method was originally declared in
  * @param mixed $pointcutQueryIdentifier Some identifier for this query - must at least differ from a previous identifier. Used for circular reference detection.
  * @return boolean TRUE if the names match, otherwise FALSE
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     if ($this->filters === null) {
         $this->buildPointcutFilters();
     }
     $matches = false;
     /** @var PointcutFilterComposite $filter */
     foreach ($this->filters as $privilegeIdentifier => $filter) {
         if ($filter->matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)) {
             $matches = true;
             $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 $matches;
 }