protected function lockAndSend(array $invoice, Source $invoiceSource, Result $result)
    {
        $doLock = !$this->isTestMode() && in_array($result->getSendStatus(), array(Result::Send_New, Result::Send_LockExpired));

        if ($doLock) {
            // Check if we may expect an expired lock and, if so, remove it.
            if ($result->getSendStatus() === Result::Send_LockExpired) {
                $lockStatus = $this->getAcumulusEntryManager()->deleteLock($invoiceSource);
                if ($lockStatus === AcumulusEntry::Lock_BecameRealEntry) {
                    // Bail out: invoice already sent after all.
                    return $result->setSendStatus(Result::NotSent_AlreadySent);
                }
            }

            // Acquire lock.
            if (!$this->getAcumulusEntryManager()->lockForSending($invoiceSource)) {
                // Bail out: Lock not acquired.
                return $result->setSendStatus(Result::NotSent_LockedForSending);
            }
        }

        try {
            $result = $this->doSend($invoice, $invoiceSource, $result);
        } catch (Exception $e) {
            $result->setException($e);
        }

        // When everything went well, the lock will have been replaced by a real
        // entry. So we only delete the lock in case of errors.
        if ($doLock && $result->hasError()) {
            // deleteLock() is expected to return AcumulusEntry::Lock_Deleted,
            // so we don't act on that return status. With any of the other
            // statuses it is unclear what happened and what the status will be
            // in Acumulus: tell user to check.
            if (($lockStatus = $this->getAcumulusEntryManager()->deleteLock($invoiceSource)) !== AcumulusEntry::Lock_Deleted) {
                $code = $lockStatus === AcumulusEntry::Lock_NoLongerExists ? 903 : 904;
                $result->addWarning($code, '',
                    sprintf($this->t('message_warning_delete_lock_failed'), $this->t($invoiceSource->getType())));
            }
        }

        // Trigger the InvoiceSent event.
        $this->triggerInvoiceSendAfter($invoice, $invoiceSource, $result);

        // Send a mail if there are messages.
        $this->mailInvoiceAddResult($result, $invoiceSource);

        return $result;
    }