/**
  * Perform all the needed checks to delete one (or more) objects
  */
 public static function DeleteObjects(WebPage $oP, $sClass, $aObjects, $bPreview, $sCustomOperation, $aContextData = array())
 {
     $oDeletionPlan = new DeletionPlan();
     foreach ($aObjects as $oObj) {
         if ($bPreview) {
             $oObj->CheckToDelete($oDeletionPlan);
         } else {
             $oObj->DBDeleteTracked(CMDBObject::GetCurrentChange(), null, $oDeletionPlan);
         }
     }
     if ($bPreview) {
         if (count($aObjects) == 1) {
             $oObj = $aObjects[0];
             $oP->add("<h1>" . Dict::Format('UI:Delete:ConfirmDeletionOf_Name', $oObj->GetName()) . "</h1>\n");
         } else {
             $oP->add("<h1>" . Dict::Format('UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . "</h1>\n");
         }
         // Explain what should be done
         //
         $aDisplayData = array();
         foreach ($oDeletionPlan->ListDeletes() as $sTargetClass => $aDeletes) {
             foreach ($aDeletes as $iId => $aData) {
                 $oToDelete = $aData['to_delete'];
                 $bAutoDel = $aData['mode'] == DEL_SILENT || $aData['mode'] == DEL_AUTO;
                 if (array_key_exists('issue', $aData)) {
                     if ($bAutoDel) {
                         if (isset($aData['requested_explicitely'])) {
                             $sConsequence = Dict::Format('UI:Delete:CannotDeleteBecause', $aData['issue']);
                         } else {
                             $sConsequence = Dict::Format('UI:Delete:ShouldBeDeletedAtomaticallyButNotPossible', $aData['issue']);
                         }
                     } else {
                         $sConsequence = Dict::Format('UI:Delete:MustBeDeletedManuallyButNotPossible', $aData['issue']);
                     }
                 } else {
                     if ($bAutoDel) {
                         if (isset($aData['requested_explicitely'])) {
                             $sConsequence = '';
                             // not applicable
                         } else {
                             $sConsequence = Dict::S('UI:Delete:WillBeDeletedAutomatically');
                         }
                     } else {
                         $sConsequence = Dict::S('UI:Delete:MustBeDeletedManually');
                     }
                 }
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToDelete)), 'object' => $oToDelete->GetHyperLink(), 'consequence' => $sConsequence);
             }
         }
         foreach ($oDeletionPlan->ListUpdates() as $sRemoteClass => $aToUpdate) {
             foreach ($aToUpdate as $iId => $aData) {
                 $oToUpdate = $aData['to_reset'];
                 if (array_key_exists('issue', $aData)) {
                     $sConsequence = Dict::Format('UI:Delete:CannotUpdateBecause_Issue', $aData['issue']);
                 } else {
                     $sConsequence = Dict::Format('UI:Delete:WillAutomaticallyUpdate_Fields', $aData['attributes_list']);
                 }
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToUpdate)), 'object' => $oToUpdate->GetHyperLink(), 'consequence' => $sConsequence);
             }
         }
         $iImpactedIndirectly = $oDeletionPlan->GetTargetCount() - count($aObjects);
         if ($iImpactedIndirectly > 0) {
             if (count($aObjects) == 1) {
                 $oObj = $aObjects[0];
                 $oP->p(Dict::Format('UI:Delete:Count_Objects/LinksReferencing_Object', $iImpactedIndirectly, $oObj->GetName()));
             } else {
                 $oP->p(Dict::Format('UI:Delete:Count_Objects/LinksReferencingTheObjects', $iImpactedIndirectly));
             }
             $oP->p(Dict::S('UI:Delete:ReferencesMustBeDeletedToEnsureIntegrity'));
         }
         if ($iImpactedIndirectly > 0 || $oDeletionPlan->FoundStopper()) {
             $aDisplayConfig = array();
             $aDisplayConfig['class'] = array('label' => 'Class', 'description' => '');
             $aDisplayConfig['object'] = array('label' => 'Object', 'description' => '');
             $aDisplayConfig['consequence'] = array('label' => 'Consequence', 'description' => Dict::S('UI:Delete:Consequence+'));
             $oP->table($aDisplayConfig, $aDisplayData);
         }
         if ($oDeletionPlan->FoundStopper()) {
             if ($oDeletionPlan->FoundSecurityIssue()) {
                 $oP->p(Dict::S('UI:Delete:SorryDeletionNotAllowed'));
             } elseif ($oDeletionPlan->FoundManualOperation()) {
                 $oP->p(Dict::S('UI:Delete:PleaseDoTheManualOperations'));
             } else {
                 $oP->p(Dict::S('UI:Delete:PleaseDoTheManualOperations'));
             }
             $oAppContext = new ApplicationContext();
             $oP->add("<form method=\"post\">\n");
             $oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"" . utils::ReadParam('transaction_id') . "\">\n");
             $oP->add("<input type=\"button\" onclick=\"window.history.back();\" value=\"" . Dict::S('UI:Button:Back') . "\">\n");
             $oP->add("<input DISABLED type=\"submit\" name=\"\" value=\"" . Dict::S('UI:Button:Delete') . "\">\n");
             $oP->add($oAppContext->GetForForm());
             $oP->add("</form>\n");
         } else {
             if (count($aObjects) == 1) {
                 $oObj = $aObjects[0];
                 $id = $oObj->GetKey();
                 $oP->p('<h1>' . Dict::Format('UI:Delect:Confirm_Object', $oObj->GetHyperLink()) . '</h1>');
             } else {
                 $oP->p('<h1>' . Dict::Format('UI:Delect:Confirm_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . '</h1>');
             }
             foreach ($aObjects as $oObj) {
                 $aKeys[] = $oObj->GetKey();
             }
             $oFilter = new DBObjectSearch($sClass);
             $oFilter->AddCondition('id', $aKeys, 'IN');
             $oSet = new CMDBobjectSet($oFilter);
             $oP->add('<div id="0">');
             CMDBAbstractObject::DisplaySet($oP, $oSet, array('display_limit' => false, 'menu' => false));
             $oP->add("</div>\n");
             $oP->add("<form method=\"post\">\n");
             foreach ($aContextData as $sKey => $value) {
                 $oP->add("<input type=\"hidden\" name=\"{$sKey}\" value=\"{$value}\">\n");
             }
             $oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"" . utils::GetNewTransactionId() . "\">\n");
             $oP->add("<input type=\"hidden\" name=\"operation\" value=\"{$sCustomOperation}\">\n");
             $oP->add("<input type=\"hidden\" name=\"filter\" value=\"" . $oFilter->Serialize() . "\">\n");
             $oP->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">\n");
             foreach ($aObjects as $oObj) {
                 $oP->add("<input type=\"hidden\" name=\"selectObject[]\" value=\"" . $oObj->GetKey() . "\">\n");
             }
             $oP->add("<input type=\"button\" onclick=\"window.history.back();\" value=\"" . Dict::S('UI:Button:Back') . "\">\n");
             $oP->add("<input type=\"submit\" name=\"\" value=\"" . Dict::S('UI:Button:Delete') . "\">\n");
             $oAppContext = new ApplicationContext();
             $oP->add($oAppContext->GetForForm());
             $oP->add("</form>\n");
         }
     } else {
         // Execute the deletion
         //
         if (count($aObjects) == 1) {
             $oObj = $aObjects[0];
             $oP->add("<h1>" . Dict::Format('UI:Title:DeletionOf_Object', $oObj->GetName()) . "</h1>\n");
         } else {
             $oP->add("<h1>" . Dict::Format('UI:Title:BulkDeletionOf_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . "</h1>\n");
         }
         // Security - do not allow the user to force a forbidden delete by the mean of page arguments...
         if ($oDeletionPlan->FoundSecurityIssue()) {
             throw new CoreException(Dict::S('UI:Error:NotEnoughRightsToDelete'));
         }
         if ($oDeletionPlan->FoundManualOperation()) {
             throw new CoreException(Dict::S('UI:Error:CannotDeleteBecauseManualOpNeeded'));
         }
         if ($oDeletionPlan->FoundManualDelete()) {
             throw new CoreException(Dict::S('UI:Error:CannotDeleteBecauseOfDepencies'));
         }
         // Report deletions
         //
         $aDisplayData = array();
         foreach ($oDeletionPlan->ListDeletes() as $sTargetClass => $aDeletes) {
             foreach ($aDeletes as $iId => $aData) {
                 $oToDelete = $aData['to_delete'];
                 if (isset($aData['requested_explicitely'])) {
                     $sMessage = Dict::S('UI:Delete:Deleted');
                 } else {
                     $sMessage = Dict::S('UI:Delete:AutomaticallyDeleted');
                 }
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToDelete)), 'object' => $oToDelete->GetName(), 'consequence' => $sMessage);
             }
         }
         // Report updates
         //
         foreach ($oDeletionPlan->ListUpdates() as $sTargetClass => $aToUpdate) {
             foreach ($aToUpdate as $iId => $aData) {
                 $oToUpdate = $aData['to_reset'];
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToUpdate)), 'object' => $oToUpdate->GetHyperLink(), 'consequence' => Dict::Format('UI:Delete:AutomaticResetOf_Fields', $aData['attributes_list']));
             }
         }
         // Report automatic jobs
         //
         if ($oDeletionPlan->GetTargetCount() > 0) {
             if (count($aObjects) == 1) {
                 $oObj = $aObjects[0];
                 $oP->p(Dict::Format('UI:Delete:CleaningUpRefencesTo_Object', $oObj->GetName()));
             } else {
                 $oP->p(Dict::Format('UI:Delete:CleaningUpRefencesTo_Several_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)));
             }
             $aDisplayConfig = array();
             $aDisplayConfig['class'] = array('label' => 'Class', 'description' => '');
             $aDisplayConfig['object'] = array('label' => 'Object', 'description' => '');
             $aDisplayConfig['consequence'] = array('label' => 'Done', 'description' => Dict::S('UI:Delete:Done+'));
             $oP->table($aDisplayConfig, $aDisplayData);
         }
     }
 }