protected function execute(InputInterface $input, OutputInterface $output)
 {
     $outputDir = $input->getOption('output-dir');
     $dump = Dump::load($outputDir);
     $dump->attachmentsDir = "{$outputDir}/attachments";
     assert_writable_dir($dump->attachmentsDir);
     $dump->write();
     $output->writeln('Get authenticated client.');
     $client = $this->getClient($input);
     $output->writeln('Start downloading files.');
     $progress = new ProgressBar($output, $dump->getTotalAttachmentSize());
     $progress->start();
     foreach ($dump->projects as $project) {
         foreach ($project->stories as $story) {
             foreach ($story->attachments as $attachment) {
                 $path = $dump->getAttachmentPath($attachment);
                 $this->downloadAttachment($client, $path, $project, $story, $attachment);
                 $progress->advance($attachment->sizeInBytes);
             }
         }
     }
     $progress->finish();
     $output->writeln('');
     $maxSize = round($dump->getBiggestAttachmentSize() / 1024);
     $output->writeln("Please ensure that Redmine maximum attachment size is greater than {$maxSize}.");
 }
 protected function initialize(InputInterface $input, OutputInterface $output)
 {
     $token = $input->getOption('agilezen-key');
     $outputDir = $input->getOption('output-dir');
     if (strlen($token) <= 0 || strlen($outputDir) <= 0) {
         throw new \RuntimeException('Both --output-dir and --agilezen-key are mandatory.');
     }
     $this->outputDir = $outputDir;
     $apiDir = "{$outputDir}/api";
     assert_writable_dir($this->outputDir);
     assert_writable_dir($apiDir);
     $this->api = new AgileZen(['token' => $token, 'cache' => true, 'cacheDir' => $apiDir]);
 }