/**
  * @param string               $name
  * @param CertificationContext $context
  * @param string[]             $providers
  *
  * @return Certification
  * @throws \Exception
  */
 public function createNamed($name, CertificationContext $context, array $providers)
 {
     if (empty($providers)) {
         $exception = new \Exception('You must define at least one provider');
         if (null !== $this->logger) {
             $this->logger->critical(sprintf('Impossible to generate certification %s, following error : "%s"', $name, $exception->getMessage()));
         }
         throw $exception;
     }
     if ($name !== $context->getName()) {
         $exception = new \Exception(sprintf('The current certification context is not for certification call %s', $name));
         if (null !== $this->logger) {
             $this->logger->critical(sprintf('Impossible to generate certification %s, following error : "%s"', $name, $exception->getMessage()));
         }
         throw $exception;
     }
     //Avoid to regenerate certification previously generated
     if (null !== $this->loader && false === $context->getDebug()) {
         try {
             if (null !== $this->logger) {
                 $this->logger->debug(sprintf('Certification %s loaded from previous dump via %s', $name, get_class($this->loader)));
             }
             return $this->loader->load($name);
         } catch (NotAlreadyDumpedException $e) {
             if (null !== $this->logger) {
                 $this->logger->debug(sprintf('Certification %s will be fully generated', $name));
             }
         }
     }
     //Check if required provider are loads
     foreach ($providers as $provider) {
         if (!$this->providerRegistry->isRegister($provider)) {
             $exception = new \Exception(sprintf('Provider %s is not registered. Did you mean %s', $provider, implode(', ', $this->providerRegistry->getRegistered())));
             if (null !== $this->logger) {
                 $this->logger->critical(sprintf('Impossible to generate certification %s, following error : "%s"', $name, $exception->getMessage()));
             }
             throw $exception;
         }
         $this->builder->addBuilderPass(new ProviderBuilderPass($this->providerRegistry->getProvider($provider)));
     }
     $certification = $this->builder->build($context);
     //Dump for next usage
     if (false === $context->getDebug() && null !== $this->dumper) {
         if (null !== $this->logger) {
             $this->logger->debug(sprintf('Dump certification %s via : %s', $name, get_class($this->dumper)));
         }
         $this->dumper->dump($certification, $context);
     }
     return $certification;
 }
 /**
  * @param array $data
  *
  * @return CertificationContext
  */
 public static function __set_state(array $data)
 {
     $certificationContext = new CertificationContext($data['name']);
     $certificationContext->setNumberOfQuestions($data['numberOfQuestions']);
     $certificationContext->setExcludeCategories($data['excludeCategories']);
     $certificationContext->setExcludeQuestions($data['excludeQuestions']);
     $certificationContext->setLanguage($data['language']);
     $certificationContext->setThreshold($data['threshold']);
     $certificationContext->setDebug($data['debug']);
     $certificationContext->setLabel($data['label']);
     $certificationContext->setAvailableLevels($data['availableLevels']);
     $certificationContext->setLevel($data['level']);
     $certificationContext->setAvailableLanguages($data['availableLanguages']);
     $certificationContext->setAllowExcludeCategories($data['allowExcludeCategories']);
     $certificationContext->setAllowCustomNumberOfQuestions($data['allowCustomNumberOfQuestions']);
     $certificationContext->setIcons($data['icons']);
     return $certificationContext;
 }