/**
  * @return string
  */
 public function ServiceAjax()
 {
     @\ob_start();
     $aResponseItem = null;
     $oException = null;
     $sAction = $this->oHttp->GetPost('Action', null);
     if (empty($sAction) && $this->oHttp->IsGet() && !empty($this->aPaths[2])) {
         $sAction = $this->aPaths[2];
     }
     try {
         if ($this->oHttp->IsPost() && !in_array($sAction, array('JsInfo', 'JsError')) && $this->Config()->Get('security', 'csrf_protection', false) && $this->oHttp->GetPost('XToken', '') !== \RainLoop\Utils::GetCsrfToken()) {
             throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidToken);
         } else {
             if (!empty($sAction)) {
                 $sMethodName = 'Do' . $sAction;
                 $this->Logger()->Write('Action: ' . $sMethodName, \MailSo\Log\Enumerations\Type::NOTE, 'AJAX');
                 $aPost = $this->oHttp->GetPostAsArray();
                 if (\is_array($aPost) && 0 < \count($aPost)) {
                     $this->oActions->SetActionParams($aPost, $sMethodName);
                     switch ($sMethodName) {
                         case 'DoLogin':
                         case 'DoAdminLogin':
                         case 'DoAccountAdd':
                             $this->Logger()->AddSecret($this->oActions->GetActionParam('Password', ''));
                             break;
                         case 'DoChangePassword':
                             $this->Logger()->AddSecret($this->oActions->GetActionParam('PrevPassword', ''));
                             $this->Logger()->AddSecret($this->oActions->GetActionParam('NewPassword', ''));
                             break;
                     }
                     $this->Logger()->Write(\MailSo\Base\Utils::Php2js($aPost, $this->Logger()), \MailSo\Log\Enumerations\Type::INFO, 'POST', true);
                 } else {
                     if (3 < \count($this->aPaths) && $this->oHttp->IsGet()) {
                         $this->oActions->SetActionParams(array('RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3]), $sMethodName);
                     }
                 }
                 if (\method_exists($this->oActions, $sMethodName) && \is_callable(array($this->oActions, $sMethodName))) {
                     $this->Plugins()->RunHook('ajax.action-pre-call', array($sAction));
                     $aResponseItem = \call_user_func(array($this->oActions, $sMethodName));
                     $this->Plugins()->RunHook('ajax.action-post-call', array($sAction, &$aResponseItem));
                 } else {
                     if ($this->Plugins()->HasAdditionalAjax($sMethodName)) {
                         $this->Plugins()->RunHook('ajax.action-pre-call', array($sAction));
                         $aResponseItem = $this->Plugins()->RunAdditionalAjax($sMethodName);
                         $this->Plugins()->RunHook('ajax.action-post-call', array($sAction, &$aResponseItem));
                     }
                 }
             }
         }
         if (!\is_array($aResponseItem)) {
             throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError);
         }
     } catch (\Exception $oException) {
         $aResponseItem = $this->oActions->ExceptionResponse(empty($sAction) ? 'Unknown' : $sAction, $oException);
         if (\is_array($aResponseItem) && $oException instanceof \RainLoop\Exceptions\ClientException) {
             if ('Folders' === $sAction) {
                 $aResponseItem['ClearAuth'] = true;
             }
             if ($oException->getLogoutOnException()) {
                 $aResponseItem['Logout'] = true;
                 if ($oException->getAdditionalMessage()) {
                     $this->oActions->SetSpecLogoutCustomMgsWithDeletion($oException->getAdditionalMessage());
                 }
             }
         }
     }
     if (\is_array($aResponseItem)) {
         $aResponseItem['Time'] = (int) ((\microtime(true) - APP_START) * 1000);
     }
     $this->Plugins()->RunHook('filter.ajax-response', array($sAction, &$aResponseItem));
     @\header('Content-Type: application/json; charset=utf-8');
     $sResult = \MailSo\Base\Utils::Php2js($aResponseItem, $this->Logger());
     $sObResult = @\ob_get_clean();
     if ($this->Logger()->IsEnabled()) {
         if (0 < \strlen($sObResult)) {
             $this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA');
         }
         if ($oException) {
             $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
         }
         $iLimit = (int) $this->Config()->Get('labs', 'log_ajax_response_write_limit', 0);
         $this->Logger()->Write(0 < $iLimit && $iLimit < \strlen($sResult) ? \substr($sResult, 0, $iLimit) . '...' : $sResult, \MailSo\Log\Enumerations\Type::INFO, 'AJAX');
     }
     return $sResult;
 }