public function getMetadata($controllerName, $actionName = null, $technology = Context::TECH_GENERIC)
 {
     if (!$this->reader) {
         return null;
     }
     $key = $controllerName . '::' . $actionName;
     if (array_key_exists($key, $this->cache)) {
         return $this->cache[$key];
     }
     $metadata = null;
     if (!is_array($this->namespaces[$technology])) {
         $this->namespaces[$technology] = [];
     }
     $className = $this->getControllerClassName($controllerName, $technology);
     if ($technology == Context::TECH_WEB && !$className) {
         $className = $this->getControllerClassName($controllerName, Context::TECH_GENERIC);
     }
     $classExists = class_exists($className);
     if (!$classExists && $technology == Context::TECH_REST) {
         $className = 'App\\Rest\\Controller';
         $classExists = true;
     }
     if ($classExists) {
         $metadata = new ContextMetadata();
         if (!$actionName) {
             $metadata->setMappedTo($controllerName);
         }
         /** @var Description $classDescr */
         $classDescr = $actionName ? null : $this->reader->getClassAnnotation($className, 'VulnModule\\Config\\Annotations\\Description');
         /** @var Route $classRouter */
         $classRouter = $this->reader->getClassAnnotation($className, 'VulnModule\\Config\\Annotations\\Route');
         /** @var ContextAnnotation $classContext */
         $classContext = $actionName ? null : $this->reader->getClassAnnotation($className, 'VulnModule\\Config\\Annotations\\Context');
         if ($classDescr) {
             if ($classDescr->description) {
                 $metadata->setDescription($classDescr->description);
             }
         }
         if ($classRouter) {
             if ($classRouter->name) {
                 $metadata->setRoute($classRouter->name);
             }
             $metadata->setRouteParams($classRouter->params);
         }
         if ($classContext) {
             $metadata->setName($classContext->name);
         }
         if (!$actionName) {
             $metadata->setType(Context::TYPE_CONTROLLER);
         }
     } else {
         $this->cache[$key] = null;
         return null;
     }
     if (!$actionName) {
         $this->cache[$key] = $metadata;
         return $metadata;
     }
     $metadata->setType(Context::TYPE_ACTION);
     $metadata->setMappedTo($actionName);
     $methodName = $this->getMethodNameByActionName($actionName, $technology);
     /** @var Description $methodDescr */
     $methodDescr = $this->reader->getMethodAnnotation($className, $methodName, 'VulnModule\\Config\\Annotations\\Description', true);
     /** @var Route $methodRoute */
     $methodRoute = $this->reader->getMethodAnnotation($className, $methodName, 'VulnModule\\Config\\Annotations\\Route', true);
     /** @var ContextAnnotation $methodContext */
     $methodContext = $this->reader->getMethodAnnotation($className, $methodName, 'VulnModule\\Config\\Annotations\\Context', true);
     if ($methodDescr) {
         if ($methodDescr->description) {
             $metadata->setDescription($methodDescr->description);
         }
     }
     if ($methodRoute) {
         if ($methodRoute->name) {
             $metadata->setRoute($methodRoute->name);
         }
         $metadata->setRouteParams($methodRoute->params);
     }
     if ($methodContext) {
         if ($methodContext->name) {
             $metadata->setName($methodContext->name);
         }
     }
     $this->cache[$key] = $metadata;
     return $metadata;
 }