private function getAdvicesFromAdvisor(
        ReflectionClass $class,
        Aop\PointcutAdvisor $advisor,
        string $advisorId,
        Aop\PointFilter $filter
    ): array {
        $classAdvices = [];
        $filterKind   = $filter->getKind();

        // Check class only for class filters
        if ($filterKind & Aop\PointFilter::KIND_CLASS) {
            if ($filter->matches($class)) {
                // Dynamic initialization
                if ($filterKind & Aop\PointFilter::KIND_INIT) {
                    $classAdvices[AspectContainer::INIT_PREFIX]['root'][$advisorId] = $advisor->getAdvice();
                }
                // Static initalization
                if ($filterKind & Aop\PointFilter::KIND_STATIC_INIT) {
                    $classAdvices[AspectContainer::STATIC_INIT_PREFIX]['root'][$advisorId] = $advisor->getAdvice();
                }
            }
        }

        // Check methods in class only for method filters
        if ($filterKind & Aop\PointFilter::KIND_METHOD) {
            $mask = ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED;
            foreach ($class->getMethods($mask) as $method) {
                // abstract and parent final methods could not be woven
                $isParentFinalMethod = ($method->getDeclaringClass()->name !== $class->name) && $method->isFinal();
                if ($isParentFinalMethod || $method->isAbstract()) {
                    continue;
                }

                if ($filter->matches($method, $class)) {
                    $prefix = $method->isStatic() ? AspectContainer::STATIC_METHOD_PREFIX : AspectContainer::METHOD_PREFIX;
                    $classAdvices[$prefix][$method->name][$advisorId] = $advisor->getAdvice();
                }
            }
        }

        // Check properties in class only for property filters
        if ($filterKind & Aop\PointFilter::KIND_PROPERTY) {
            $mask = ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE;
            foreach ($class->getProperties($mask) as $property) {
                if ($filter->matches($property, $class) && !$property->isStatic()) {
                    $classAdvices[AspectContainer::PROPERTY_PREFIX][$property->name][$advisorId] = $advisor->getAdvice();
                }
            }
        }

        return $classAdvices;
    }