public function doCheck($object, IPermission $perm, LoginContext $context = null)
 {
     if (SecurityManager::$Logger->isDebugEnabled()) {
         SecurityManager::$Logger->debug('Preparing to check permission with login context:');
         SecurityManager::$Logger->debug(print_r($context, true));
     }
     // A little "hack" here to avoid any lock to the root user due to configuration problem
     // in the next steps (= even without any configuration or with a broken configuration file,
     // the root will always have all the permissions on everything)
     $eyeosUser = null;
     try {
         $eyeosUser = $context->getEyeosUser();
         if ($eyeosUser->getName() === 'root') {
             if (SecurityManager::$Logger->isInfoEnabled()) {
                 SecurityManager::$Logger->info('Root user found in login context: bypassing any further security check for requested permission ' . $perm . '.');
             }
             return;
         }
     } catch (EyeNullPointerException $e) {
     }
     $configuration = PolicyConfiguration::getConfiguration();
     // Browse policy entries until we find one that matches the class of our object
     foreach ($configuration->getPolicyEntries() as $policyEntry) {
         $objectClass = $policyEntry->getObjectClass();
         if ($object instanceof $objectClass) {
             // Check permission using each handler defined for this entry
             foreach ($policyEntry->getHandlerEntries() as $handlerEntry) {
                 try {
                     $handler = SecurityManager::getNewHandlerInstance($handlerEntry->getHandlerClass(), $handlerEntry->getParams());
                     try {
                         $status = $handler->checkPermission($object, $perm, $context);
                         // SUCCESS (access granted byt the current handler)
                         if ($status === true) {
                             if ($handlerEntry->getFlag() == PolicyHandlerEntry::FLAG_SUFFICIENT) {
                                 if ($this->firstRequiredError === null) {
                                     return;
                                 }
                             }
                             $this->success = true;
                         } else {
                             if (SecurityManager::$Logger->isInfoEnabled()) {
                                 $failureExceptionMessage = '(none available)';
                                 if ($handler->getFailureException() !== null) {
                                     $failureExceptionMessage = $handler->getFailureException()->getMessage();
                                 }
                                 SecurityManager::$Logger->debug($handlerEntry->getHandlerClass() . ' failure message: ' . $failureExceptionMessage);
                             }
                         }
                     } catch (EyeSecurityException $e) {
                         if ($handlerEntry->getFlag() == PolicyHandlerEntry::FLAG_REQUISITE) {
                             if (SecurityManager::$Logger->isInfoEnabled()) {
                                 SecurityManager::$Logger->info('Requested permission ' . $perm . ' denied object of class ' . get_class($object) . ' (REQUISITE handler ' . $handlerEntry->getHandlerClass() . ' failed).');
                                 SecurityManager::$Logger->info($e->getMessage());
                             }
                             $this->throwException($this->firstRequiredError, $e);
                         } else {
                             if ($handlerEntry->getFlag() == PolicyHandlerEntry::FLAG_REQUIRED) {
                                 if ($this->firstRequiredError === null) {
                                     $this->firstRequiredError = $e;
                                 }
                             } else {
                                 if ($this->firstError === null) {
                                     $this->firstError = $e;
                                 }
                             }
                         }
                     }
                 } catch (EyeException $e) {
                     $this->throwException(null, $e);
                 }
             }
             if ($this->firstRequiredError !== null) {
                 // A required handler failed
                 if (SecurityManager::$Logger->isInfoEnabled()) {
                     SecurityManager::$Logger->info('Requested permission ' . $perm . ' denied on object of class ' . get_class($object) . ' (a REQUIRED handler failed).');
                     SecurityManager::$Logger->info($this->firstRequiredError->getMessage());
                 }
                 $this->throwException($this->firstRequiredError, null);
             } else {
                 if (!$this->success && $this->firstError !== null) {
                     // No handler succeeded: return the first error
                     if (SecurityManager::$Logger->isInfoEnabled()) {
                         SecurityManager::$Logger->info('Requested permission ' . $perm . ' denied on object of class ' . get_class($object) . '.');
                         SecurityManager::$Logger->info($this->firstError->getMessage());
                     }
                     $this->throwException($this->firstError, null);
                 } else {
                     if (!$this->success) {
                         // All handlers returned FALSE (= they could not perform permission checks for any reason)
                         SecurityManager::$Logger->warn('All SecurityHandlers have been ignored for object of class ' . get_class($object) . '.');
                         $this->throwException(new EyeSecurityException('Permission check failure: all handlers ignored on object of class "' . $objectClass . '".'), null);
                     } else {
                         if (SecurityManager::$Logger->isDebugEnabled()) {
                             SecurityManager::$Logger->debug('Permission ' . $perm . ' granted on object of class ' . get_class($object) . '.');
                         }
                         return;
                     }
                 }
             }
         }
     }
     // No matching policy entry has been found for given $object: report it in the log and allow access
     if (!$this->success) {
         SecurityManager::$Logger->warn('No matching policy entry for object of class ' . get_class($object) . ' has been found.');
     }
 }