/**
  * Constructor
  *
  * Optionally accept the project root directory; if non-empty, it is used
  * to prefix the $configFile.
  *
  * @param mixed $injectors
  * @param DiscoveryChainInterface $discoveryChain
  * @param Collection $availableTypes
  * @param string $projectRoot
  */
 public function __construct($injectors, DiscoveryChainInterface $discoveryChain, Collection $availableTypes, $projectRoot = '')
 {
     $this->chain = Collection::create($injectors)->filter(function ($injector, $file) use($discoveryChain) {
         return $discoveryChain->discoveryExists($file);
     })->map(function ($injector) use($projectRoot) {
         return new $injector($projectRoot);
     })->filter(function ($injector) use($availableTypes) {
         return $availableTypes->reduce(function ($flag, $type) use($injector) {
             return $flag || $injector->registersType($type);
         }, false);
     });
 }
 /**
  * Prompt for the user to select a configuration location to update.
  *
  * @param string $name
  * @param Collection $options
  * @param int $packageType
  * @return Injector\InjectorInterface
  */
 private function promptForConfigOption($name, Collection $options, $packageType)
 {
     if ($cachedInjector = $this->getCachedInjector($packageType)) {
         return $cachedInjector;
     }
     $ask = $options->reduce(function ($ask, $option, $index) {
         $ask[] = sprintf("  [<comment>%d</comment>] %s\n", $index, $option->getPromptText());
         return $ask;
     }, []);
     array_unshift($ask, sprintf("\n  <question>Please select which config file you wish to inject '%s' into:</question>\n", $name));
     array_push($ask, '  Make your selection (default is <comment>0</comment>):');
     while (true) {
         $answer = $this->io->ask($ask, 0);
         if (is_numeric($answer) && isset($options[(int) $answer])) {
             $injector = $options[(int) $answer]->getInjector();
             $this->promptToRememberOption($injector, $packageType);
             return $injector;
         }
         $this->io->write('<error>Invalid selection</error>');
     }
 }
 /**
  * Attempt to retrieve a cached injector, based on the current package types.
  *
  * @param Collection $packageTypes
  * @return null|Injector\InjectorInterface
  */
 private function getCachedInjector(Collection $packageTypes)
 {
     return $packageTypes->reduce(function ($injector, $type) {
         if (null !== $injector || !isset($this->cachedInjectors[$type])) {
             return $injector;
         }
         return $this->cachedInjectors[$type];
     }, null);
 }