/**
  * @return int|null|void
  */
 protected function serve()
 {
     $this->gpm = new GPM($this->input->getOption('force'));
     $this->all_yes = $this->input->getOption('all-yes');
     $this->overwrite = $this->input->getOption('overwrite');
     $this->displayGPMRelease();
     $this->destination = realpath($this->input->getOption('destination'));
     if (!Installer::isGravInstance($this->destination)) {
         $this->output->writeln("<red>ERROR</red>: " . Installer::lastErrorMsg());
         exit;
     }
     if ($this->input->getOption('plugins') === false && $this->input->getOption('themes') === false) {
         $list_type = ['plugins' => true, 'themes' => true];
     } else {
         $list_type['plugins'] = $this->input->getOption('plugins');
         $list_type['themes'] = $this->input->getOption('themes');
     }
     if ($this->overwrite) {
         $this->data = $this->gpm->getInstallable($list_type);
         $description = " can be overwritten";
     } else {
         $this->data = $this->gpm->getUpdatable($list_type);
         $description = " need updating";
     }
     $only_packages = array_map('strtolower', $this->input->getArgument('package'));
     if (!$this->overwrite && !$this->data['total']) {
         $this->output->writeln("Nothing to update.");
         exit;
     }
     $this->output->write("Found <green>" . $this->gpm->countInstalled() . "</green> packages installed of which <magenta>" . $this->data['total'] . "</magenta>" . $description);
     $limit_to = $this->userInputPackages($only_packages);
     $this->output->writeln('');
     unset($this->data['total']);
     unset($limit_to['total']);
     // updates review
     $slugs = [];
     $index = 0;
     foreach ($this->data as $packages) {
         foreach ($packages as $slug => $package) {
             if (count($limit_to) && !array_key_exists($slug, $limit_to)) {
                 continue;
             }
             if (!$package->available) {
                 $package->available = $package->version;
             }
             $this->output->writeln(str_pad($index++ + 1, 2, '0', STR_PAD_LEFT) . ". " . "<cyan>" . str_pad($package->name, 15) . "</cyan> " . "[v<magenta>" . $package->version . "</magenta> -> v<green>" . $package->available . "</green>]");
             $slugs[] = $slug;
         }
     }
     if (!$this->all_yes) {
         // prompt to continue
         $this->output->writeln("");
         $questionHelper = $this->getHelper('question');
         $question = new ConfirmationQuestion("Continue with the update process? [Y|n] ", true);
         $answer = $questionHelper->ask($this->input, $this->output, $question);
         if (!$answer) {
             $this->output->writeln("<red>Update aborted. Exiting...</red>");
             exit;
         }
     }
     // finally update
     $install_command = $this->getApplication()->find('install');
     $args = new ArrayInput(['command' => 'install', 'package' => $slugs, '-f' => $this->input->getOption('force'), '-d' => $this->destination, '-y' => true]);
     $command_exec = $install_command->run($args, $this->output);
     if ($command_exec != 0) {
         $this->output->writeln("<red>Error:</red> An error occurred while trying to install the packages");
         exit;
     }
 }