/**
  * Builds a single AOP proxy class for the specified class.
  *
  * @param string $targetClassName Name of the class to create a proxy class file for
  * @param array $aspectContainers The array of aspect containers from the AOP Framework
  * @param string $context The current application context
  * @return mixed An array containing the proxy class name and its source code if a proxy class has been built, otherwise FALSE
  * @author Robert Lemke <*****@*****.**>
  * @author Karsten Dambekalns <*****@*****.**>
  */
 public function buildProxyClass($targetClassName, array $aspectContainers, $context)
 {
     if ($this->reflectionService->isClassImplementationOf($targetClassName, 'F3\\FLOW3\\AOP\\ProxyInterface')) {
         throw new \F3\FLOW3\AOP\Exception\InvalidTargetClassException('Cannot proxy class "' . $targetClassName . '" because it is already an AOP proxy class.', 1238858632);
     }
     $introductions = $this->getMatchingIntroductions($aspectContainers, $targetClassName);
     $introducedInterfaces = $this->getInterfaceNamesFromIntroductions($introductions);
     $methodsFromTargetClass = $this->getMethodsFromTargetClass($targetClassName);
     $methodsFromIntroducedInterfaces = $this->getIntroducedMethodsFromIntroductions($introductions, $targetClassName);
     $interceptedMethods = array();
     $this->addAdvicedMethodsToInterceptedMethods($interceptedMethods, array_merge($methodsFromTargetClass, $methodsFromIntroducedInterfaces), $targetClassName, $aspectContainers);
     $this->addIntroducedMethodsToInterceptedMethods($interceptedMethods, $methodsFromIntroducedInterfaces);
     if (count($interceptedMethods) < 1 && count($introducedInterfaces) < 1) {
         return FALSE;
     }
     $this->addConstructorToInterceptedMethods($interceptedMethods, $targetClassName);
     $proxyClassName = $this->renderProxyClassName($targetClassName, $context);
     $proxyNamespace = $this->getProxyNamespace($targetClassName);
     $advicedMethodsInformation = $this->getAdvicedMethodsInformation($interceptedMethods);
     $proxyClassTokens = array('CLASS_ANNOTATIONS' => $this->buildClassAnnotationsCode($targetClassName), 'PROXY_NAMESPACE' => $proxyNamespace, 'PROXY_CLASS_NAME' => $proxyClassName, 'TARGET_CLASS_NAME' => $targetClassName, 'INTRODUCED_INTERFACES' => $this->buildIntroducedInterfacesCode($introducedInterfaces), 'METHODS_AND_ADVICES_ARRAY_CODE' => $this->buildMethodsAndAdvicesArrayCode($interceptedMethods), 'METHODS_INTERCEPTOR_CODE' => $this->buildMethodsInterceptorCode($interceptedMethods, $targetClassName));
     $proxyCode = $this->proxyClassTemplate;
     foreach ($proxyClassTokens as $token => $value) {
         $proxyCode = str_replace('###' . $token . '###', $value, $proxyCode);
     }
     return array('proxyClassName' => $proxyNamespace . '\\' . $proxyClassName, 'proxyClassCode' => $proxyCode, 'advicedMethodsInformation' => $advicedMethodsInformation);
 }
 /**
  * @test
  * @author Karsten Dambekalns <*****@*****.**>
  */
 public function isClassImplementationOfReturnsTrueIfClassImplementsSpecifiedInterface()
 {
     $availableClassNames = array('F3\\FLOW3\\Tests\\Reflection\\Fixture\\ImplementationOfDummyInterface1');
     $reflectionService = new \F3\FLOW3\Reflection\ReflectionService();
     $reflectionService->setStatusCache($this->getMock('F3\\FLOW3\\Cache\\Frontend\\StringFrontend', array(), array(), '', FALSE));
     $reflectionService->setDataCache($this->getMock('F3\\FLOW3\\Cache\\Frontend\\VariableFrontend', array(), array(), '', FALSE));
     $reflectionService->injectSystemLogger($this->getMock('F3\\FLOW3\\Log\\SystemLoggerInterface'));
     $reflectionService->initialize($availableClassNames);
     $this->assertTrue($reflectionService->isClassImplementationOf('F3\\FLOW3\\Tests\\Reflection\\Fixture\\ImplementationOfDummyInterface1', 'F3\\FLOW3\\Tests\\Reflection\\Fixture\\DummyInterface1'));
     $this->assertFalse($reflectionService->isClassImplementationOf('F3\\FLOW3\\Tests\\Reflection\\Fixture\\ImplementationOfDummyInterface1', 'F3\\FLOW3\\Tests\\Reflection\\Fixture\\DummyInterface2'));
 }