/**
  * @param ItemTreeBounds $itemTreeBounds
  * @param int $groupId
  * @param int[] $additionalEventIds additional event ids to include, indexed by licenseId
  * @param null|LicenseMap $licenseMap if given then license are considered as equal iff mapped to same
  * @return bool
  */
 public function hasUnhandledScannerDetectedLicenses(ItemTreeBounds $itemTreeBounds, $groupId, $additionalEventIds = array(), $licenseMap = null)
 {
     if (!empty($licenseMap) && !$licenseMap instanceof LicenseMap) {
         throw new Exception('invalid license map');
     }
     $userEvents = $this->clearingDao->getRelevantClearingEvents($itemTreeBounds, $groupId);
     $usageId = empty($licenseMap) ? LicenseMap::TRIVIAL : $licenseMap->getUsage();
     $scannerDetectedEvents = $this->agentLicenseEventProcessor->getScannerEvents($itemTreeBounds, $usageId);
     $eventLicenceIds = array();
     foreach (array_keys($userEvents) as $licenseId) {
         $eventLicenceIds[empty($licenseMap) ? $licenseId : $licenseMap->getProjectedId($licenseId)] = $licenseId;
     }
     foreach (array_keys($additionalEventIds) as $licenseId) {
         $eventLicenceIds[empty($licenseMap) ? $licenseId : $licenseMap->getProjectedId($licenseId)] = $licenseId;
     }
     foreach (array_keys($scannerDetectedEvents) as $licenseId) {
         if (!array_key_exists(empty($licenseMap) ? $licenseId : $licenseMap->getProjectedId($licenseId), $eventLicenceIds)) {
             return true;
         }
     }
     return false;
 }