/**
  * @param InputInterface $input
  * @param OutputInterface $output
  *
  * @return int
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $start = time();
     $em = $this->getContainer()->get('doctrine.orm.entity_manager');
     $dispatcher = $this->getContainer()->get('event_dispatcher');
     /* @var $rep StorageRepository */
     $rep = $em->getRepository('AnimeDbCatalogBundle:Storage');
     $progress = $this->getProgress($input, $output);
     $lazywrite = new LazyWrite($output);
     $lazywrite->setLazyWrite(!$input->getOption('no-progress'));
     // get list storages
     if ($id = $input->getArgument('storage')) {
         $storage = $rep->find($id);
         if (!$storage instanceof Storage) {
             throw new \InvalidArgumentException('Not found the storage with id: ' . $id);
         }
         if (!$storage->isWritable()) {
             throw new \InvalidArgumentException('Storage "' . $storage->getName() . '" can not be scanned');
         }
         $storages = [$storage];
     } else {
         $storages = $rep->getList(Storage::getTypesWritable());
     }
     /* @var $storage Storage */
     foreach ($storages as $storage) {
         $output->writeln('Scan storage <info>' . $storage->getName() . '</info>:');
         $path = $storage->getPath();
         $path = Utf8::wrapPath($path);
         // wrap path for current fs
         if (!file_exists($path)) {
             $output->writeln('Storage is not available');
             continue;
         }
         // check storage id
         $owner = $this->checkStorageId($path, $storage, $rep);
         if ($owner instanceof Storage) {
             $output->writeln('Path <info>' . $storage->getPath() . '</info> reserved storage <info>' . $owner->getName() . '</info>');
             continue;
         }
         // storage not modified
         if (!$input->getOption('force') && $storage->getFileModified() && filemtime($path) == $storage->getFileModified()->getTimestamp()) {
             $output->writeln('Storage is not modified');
             continue;
         }
         $files = $this->getFilesByPath($path);
         $total = $files->count();
         // total files +1% for check of delete files
         $progress->start(ceil($total + $total * 0.01));
         $progress->display();
         /* @var $file SplFileInfo */
         foreach ($files as $file) {
             // ignore not supported files
             if ($file->isFile() && !$this->isAllowFile($file)) {
                 $progress->advance();
                 continue;
             }
             // item is exists and modified
             if ($item = $this->getItemFromFile($storage, $file)) {
                 if ($item->getDateUpdate()->getTimestamp() < $file->getPathInfo()->getMTime()) {
                     $dispatcher->dispatch(StoreEvents::UPDATE_ITEM_FILES, new UpdateItemFiles($item));
                     $lazywrite->writeln('Changes are detected in files of item <info>' . $item->getName() . '</info>');
                 }
             } else {
                 // remove wrap prefix
                 list(, $file) = explode('://', $file->getPathname(), 2);
                 $file = new SplFileInfo($file, '', '');
                 // it is a new item
                 $name = $this->getContainer()->get('anime_db.storage.filename_cleaner')->clean($file);
                 $dispatcher->dispatch(StoreEvents::DETECTED_NEW_FILES, new DetectedNewFiles($storage, $file, $name));
                 $lazywrite->writeln('Detected files for new item <info>' . $file->getFilename() . '</info>');
             }
             $progress->advance();
         }
         $em->refresh($storage);
         // check of delete file for item
         foreach ($this->getItemsOfDeletedFiles($storage, $files) as $item) {
             $dispatcher->dispatch(StoreEvents::DELETE_ITEM_FILES, new DeleteItemFiles($item));
             $lazywrite->writeln('<error>Files for item "' . $item->getName() . '" is not found</error>');
         }
         $progress->advance();
         $progress->finish();
         $lazywrite->writeAll();
         // update date modified
         $storage->setFileModified(new \DateTime(date('Y-m-d H:i:s', filemtime($path))));
         $em->persist($storage);
         $output->writeln('');
     }
     $em->flush();
     $output->writeln('Time: <info>' . (time() - $start) . '</info> s.');
 }
 public function testLazyWrite()
 {
     $this->assertTrue($this->lazy_write->isLazyWrite());
     $this->lazy_write->setLazyWrite(false);
     $this->assertFalse($this->lazy_write->isLazyWrite());
 }