/**
  * Generate a REST client based on an interface
  *
  * @param ClassMetaDataProvider $classMetaDataProvider
  * @param GeneratedClassMetaDataProvider $generatedClassMetaDataProvider
  * @return string
  */
 public function generate(ClassMetaDataProvider $classMetaDataProvider, GeneratedClassMetaDataProvider $generatedClassMetaDataProvider)
 {
     // get interface methods
     $parsedMethods = $classMetaDataProvider->getInterfaceMethods();
     // loop through class annotations
     $class = new ClassModel();
     foreach ($classMetaDataProvider->getClassAnnotations() as $classAnnotation) {
         if ($classAnnotation instanceof Headers) {
             $class->addHeaders($classAnnotation->getHeaders());
         }
     }
     // loop over class methods
     foreach ($classMetaDataProvider->getReflectionMethods() as $index => $classMethod) {
         $parsedMethod = array_shift($parsedMethods);
         $parameters = $classMethod->getParameters();
         $method = new Method();
         $method->setName($classMetaDataProvider->getMethodName($parsedMethod));
         $method->setDeclaration($classMetaDataProvider->getMethodDeclaration($parsedMethod));
         // loop through method annotations
         foreach ($classMetaDataProvider->getMethodAnnotations($classMethod) as $methodAnnotation) {
             if ($methodAnnotation instanceof HttpRequest) {
                 foreach ($methodAnnotation->getParameters() as $parameter) {
                     $this->assertParameter($parameters, $parameter);
                 }
             }
             if ($methodAnnotation instanceof AnnotationToVariableMap) {
                 $this->assertParameter($parameters, $methodAnnotation->getName());
             }
             $handler = $this->annotationHandlerFactory->make($methodAnnotation);
             $handler->handle($method, $methodAnnotation);
         }
         $methodOptions = $method->getOptions();
         $methodParts = $method->getParts();
         Tebru\assert(null !== $method->getType(), new GenerationException('During Generation, the http method annotation was not found.'));
         Tebru\assert(empty($methodOptions['body']) || empty($methodParts), new GenerationException(sprintf('During Generation, both a @Body and @Part annotation were found on method "%s"', $method->getName())));
         $class->addMethod($method);
     }
     // render class as string
     $template = $this->twig->loadTemplate('service.php.twig');
     return $template->render(['uses' => $classMetaDataProvider->getUseStatements(), 'namespace' => $generatedClassMetaDataProvider->getNamespaceFull(), 'className' => $classMetaDataProvider->getInterfaceNameShort(), 'interfaceName' => $classMetaDataProvider->getInterfaceNameFull(), 'methods' => $class->getMethods()]);
 }
 /**
  * @expectedException \Tebru\Retrofit\Exception\UnknownAnnotationHandlerException
  */
 public function testFactoryThrowsException()
 {
     $factory = new AnnotationHandlerFactory();
     $factory->make(null);
 }