/**
  * @return GatewayModule
  */
 public function run()
 {
     $result = $this;
     // (1) Gateway: validate gateway, config, factory
     try {
         $this->_resetBeforeRun();
         $this->_validateGateway();
         $this->_resetModules();
     } catch (\Exception $e) {
         $this->_lastException = $e;
         $hasException = true;
         $fatalException = $this->newModuleException();
         $fatalException->setMessage($fatalException::ERROR_GATEWAY_PREPARE_FATAL_INTERNAL);
         $fatalException->setMethodInfo($this, __METHOD__, __LINE__);
         $fatalException->setFault($e);
         $this->_onErrorGatewayPrepare($fatalException);
         return $result;
     }
     // (2) RawRequest: fetch & decode text as raw request data
     try {
         $this->_rawRequestDecode();
         $this->_rawRequestValidate();
         $rawRequestData = $this->getRawRequestData();
         $this->_isRawRequestBatched = !RpcUtil::isAssocArray($rawRequestData);
     } catch (\Exception $e) {
         $this->_lastException = $e;
         $hasException = true;
         $fatalException = $this->newModuleException();
         $fatalException->setMessage($fatalException::ERROR_GATEWAY_RAW_REQUEST_INVALID);
         $fatalException->setMethodInfo($this, __METHOD__, __LINE__);
         $fatalException->setFault($e);
         $this->_onErrorRawRequestInvalid($fatalException);
         return $result;
     }
     // (3) Batch: create batch, process all rpc items
     $batch = array();
     if (!$this->_isRawRequestBatched) {
         $batch = array($rawRequestData);
     } else {
         $batch = $rawRequestData;
     }
     $this->_rpcQueue = $batch;
     $responseList = array();
     $this->_rawResponseData = $responseList;
     foreach ($batch as $itemData) {
         if (!is_array($itemData)) {
             $itemData = array();
         }
         $rpc = $this->getProcessorModule()->newRpc();
         $rpc->setGateway($this);
         $this->_rpc = $rpc;
         $rpc->getRequest()->setRawData($itemData);
         $this->_currentRpcProcess();
         $itemResponseData = $rpc->getResponse()->getReadyData();
         $responseList[] = $itemResponseData;
         $this->_rawResponseData = $responseList;
     }
     // (5) Gateway Response: create, encode, validate
     try {
         $this->_rawResponseCreate();
         $this->_rawResponseEncode();
         //$this->_rawResponseValidate();
     } catch (\Exception $e) {
         $this->_lastException = $e;
         $hasException = true;
         $fatalException = $this->newModuleException();
         $fatalException->setMessage($fatalException::ERROR_GATEWAY_RAW_RESPONSE_INVALID);
         $fatalException->setMethodInfo($this, __METHOD__, __LINE__);
         $fatalException->setFault($e);
         $this->_onErrorRawResponseInvalid($fatalException);
         return $result;
     }
     // (6) Gateway Response: emit
     try {
         if ($this->getIsAutoEmitResponseEnabled()) {
             $this->_rawResponseEmit();
         }
     } catch (\Exception $e) {
         $this->_lastException = $e;
         $hasException = true;
         $fatalException = $this->newModuleException();
         $fatalException->setMessage($fatalException::ERROR_GATEWAY_RAW_RESPONSE_EMIT_FAILED);
         $fatalException->setMethodInfo($this, __METHOD__, __LINE__);
         $fatalException->setFault($e);
         $this->_onErrorRawResponseEmitFailed($fatalException);
         return $result;
     }
     return $result;
 }