/**
  * Creates and returns an aspect from the annotations found in a class which
  * is tagged as an aspect. The object acting as an advice will already be
  * fetched (and therefore instantiated if neccessary).
  *
  * @param  string $aspectClassName Name of the class which forms the aspect, contains advices etc.
  * @return mixed The aspect container containing one or more advisors or FALSE if no container could be built
  * @author Robert Lemke <*****@*****.**>
  */
 protected function buildAspectContainer($aspectClassName)
 {
     if (!$this->reflectionService->isClassReflected($aspectClassName)) {
         return FALSE;
     }
     if (!$this->reflectionService->isClassTaggedWith($aspectClassName, 'aspect')) {
         return FALSE;
     }
     $aspectContainer = new \F3\FLOW3\AOP\AspectContainer($aspectClassName);
     foreach ($this->reflectionService->getClassMethodNames($aspectClassName) as $methodName) {
         foreach ($this->reflectionService->getMethodTagsValues($aspectClassName, $methodName) as $tagName => $tagValues) {
             foreach ($tagValues as $tagValue) {
                 switch ($tagName) {
                     case 'around':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AroundAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'before':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\BeforeAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'afterreturning':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AfterReturningAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'afterthrowing':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AfterThrowingAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'after':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AfterAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'pointcut':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName, $methodName);
                         $aspectContainer->addPointcut($pointcut);
                         break;
                 }
             }
         }
     }
     foreach ($this->reflectionService->getClassPropertyNames($aspectClassName) as $propertyName) {
         foreach ($this->reflectionService->getPropertyTagsValues($aspectClassName, $propertyName) as $tagName => $tagValues) {
             foreach ($tagValues as $tagValue) {
                 switch ($tagName) {
                     case 'introduce':
                         $splittedTagValue = explode(',', $tagValue);
                         if (!is_array($splittedTagValue) || count($splittedTagValue) != 2) {
                             throw new \F3\FLOW3\AOP\Exception('The introduction in class "' . $aspectClassName . '" does not contain the two required parameters.', 1172694761);
                         }
                         $pointcutExpression = trim($splittedTagValue[1]);
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($pointcutExpression);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                         $interfaceName = trim($splittedTagValue[0]);
                         $introduction = $this->objectFactory->create('F3\\FLOW3\\AOP\\Introduction', $aspectClassName, $interfaceName, $pointcut);
                         $aspectContainer->addIntroduction($introduction);
                         break;
                 }
             }
         }
     }
     if (count($aspectContainer->getAdvisors()) < 1 && count($aspectContainer->getPointcuts()) < 1 && count($aspectContainer->getIntroductions()) < 1) {
         throw new \F3\FLOW3\AOP\Exception('The class "' . $aspectClassName . '" is tagged to be an aspect but doesn\'t contain advices nor pointcut or introduction declarations.', 1169124534);
     }
     return $aspectContainer;
 }