public function validateSender(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     parent::validateSender($mail, $sender);
     $parts = $this->matchObjectAddressInMail($mail);
     $pattern = $parts['pattern'];
     try {
         $object = $this->loadObjectFromMail($mail, $sender);
     } catch (PhabricatorPolicyException $policy_exception) {
         throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_POLICY_PROBLEM, pht('This mail is addressed to an object ("%s") you do not have ' . 'permission to see: %s', $pattern, $policy_exception->getMessage()));
     }
     if (!$object) {
         throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_NO_SUCH_OBJECT, pht('This mail is addressed to an object ("%s"), but that object ' . 'does not exist.', $pattern));
     }
     $sender_identifier = $parts['sender'];
     if ($sender_identifier === 'public') {
         if (!PhabricatorEnv::getEnvConfig('metamta.public-replies')) {
             throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_NO_PUBLIC_MAIL, pht('This mail is addressed to the public email address of an object ' . '("%s"), but public replies are not enabled on this Phabricator ' . 'install. An administrator may have recently disabled this ' . 'setting, or you may have replied to an old message. Try ' . 'replying to a more recent message instead.', $pattern));
         }
         $check_phid = $object->getPHID();
     } else {
         if ($sender_identifier != $sender->getID()) {
             throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_USER_MISMATCH, pht('This mail is addressed to the private email address of an object ' . '("%s"), but you are not the user who is authorized to use the ' . 'address you sent mail to. Each private address is unique to the ' . 'user who received the original mail. Try replying to a message ' . 'which was sent directly to you instead.', $pattern));
         }
         $check_phid = $sender->getPHID();
     }
     $expect_hash = self::computeMailHash($object->getMailKey(), $check_phid);
     if ($expect_hash != $parts['hash']) {
         throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_HASH_MISMATCH, pht('This mail is addressed to an object ("%s"), but the address is ' . 'not correct (the security hash is wrong). Check that the address ' . 'is correct.', $pattern));
     }
 }