/**
  * Checks if the nested set fix is required
  * @param EntityManager $em
  * @param OutputInterface $output
  * @param string $entityName
  * @return boolean
  */
 protected function isFixRequired(EntityManager $em, $output, $entityName)
 {
     $repository = $em->getRepository($entityName);
     if (!$repository instanceof RepositoryInterface) {
         $output->writeln('<error>The entity name isn\'t configured to be in nested set');
         return false;
     }
     $nestedRepository = $repository->getNestedSetRepository();
     $filter = $nestedRepository->createSearchCondition();
     $order = $nestedRepository->createSelectOrderRule();
     // Order by left index
     $order->byLeftAscending();
     /* @var $nestedRepository DoctrineRepository */
     $qb = $nestedRepository->createSearchQueryBuilder($filter, $order);
     $qb->select('e');
     $query = $qb->getQuery();
     $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
     $query->setHydrationMode(Query::HYDRATE_SIMPLEOBJECT);
     $records = $query->getResult();
     // Keeps pile of current parents
     $parents = array();
     $arrayRepository = new ArrayRepository();
     $nodes = array();
     /* @var $nodes ValidationArrayNode[] */
     foreach ($records as $record) {
         if (!$record instanceof EntityNodeInterface) {
             throw new \UnexpectedValueException(sprintf('Expecting DoctrineNode, [%s] received.', get_class($record)));
         }
         $level = $record->getLevel();
         $node = new ValidationArrayNode($record);
         $nodes[] = $node;
         $arrayRepository->add($node);
         // Fixing strongly relies on the level
         if ($level > 0) {
             $parent = null;
             if (isset($parents[$level - 1])) {
                 $parent = $parents[$level - 1];
             } else {
                 // Too fast level drop, takes the deepest parent
                 $parent = end($parents);
             }
             if (!empty($parent)) {
                 $parent->addChild($node);
             }
         }
         $newLevel = $node->getLevel();
         // Removing historical parents deeper than the current node
         $parents = array_slice($parents, 0, $newLevel);
         $parents[$newLevel] = $node;
     }
     $fixRequired = false;
     foreach ($nodes as $node) {
         if (!$node->isOk()) {
             // Output index changes suggested
             $output->writeln("Node " . $node->getNodeTitle());
             $dbEntity = $em->find($entityName, $node->getId());
             /* @var $dbEntity EntityNodeInterface */
             if (!$node->isLeaf() && $node->isOriginallyWithLeafInterface()) {
                 $children = $node->getChildren();
                 foreach ($children as $child) {
                     if (!$node->isOk()) {
                         $child->moveAsNextSiblingOf($node);
                     } else {
                         $child->moveAsPrevSiblingOf($node);
                     }
                 }
             } else {
                 // Overwrite the indices
                 $dbEntity->setLeftValue($node->getLeftValue());
                 $dbEntity->setRightValue($node->getRightValue());
                 $dbEntity->setLevel($node->getLevel());
             }
             $fixRequired = true;
         }
     }
     // Flushing, commit or rollback done later
     if ($fixRequired) {
         $em->flush();
     }
     return $fixRequired;
 }