protected function createAndSend(Source $invoiceSource, Result $result, $forceSend = false, $dryRun = false)
    {
        $acumulusEntry = null;
        if ($this->isTestMode()) {
            $result->setSendStatus(Result::Send_TestMode);
        } elseif (($acumulusEntry = $this->getAcumulusEntryManager()->getByInvoiceSource($invoiceSource, false)) === null) {
            $result->setSendStatus(Result::Send_New);
        } elseif ($forceSend) {
            $result->setSendStatus(Result::Send_Forced);
        } elseif ($acumulusEntry->hasLockExpired()) {
            $result->setSendStatus(Result::Send_LockExpired);
        } elseif ($acumulusEntry->isSendLock()) {
            $result->setSendStatus(Result::NotSent_LockedForSending);
        } else {
            $result->setSendStatus(Result::NotSent_AlreadySent);
        }

        if (($result->getSendStatus() & Result::Send_Mask) !== 0) {
            $invoice = $this->getCreator()->create($invoiceSource);

            // Do not send 0-amount invoices, if set so.
            $shopEventSettings = $this->getConfig()->getShopEventSettings();
            if ($shopEventSettings['sendEmptyInvoice'] || !$this->isEmptyInvoice($invoice)) {
                // Trigger the InvoiceCreated event.
                $this->triggerInvoiceCreated($invoice, $invoiceSource, $result);

                // If the invoice is not set to null, we continue by completing it.
                if ($invoice !== null) {
                    $invoice = $this->getCompletor()->complete($invoice, $invoiceSource, $result);

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

                    // If the invoice is not set to null, we continue by sending it.
                    if ($invoice !== null) {
                        if (!$result->hasError()) {
                            if (!$dryRun) {
                                $result = $this->lockAndSend($invoice, $invoiceSource, $result);
                            } else {
                                $result->setSendStatus(Result::NotSent_DryRun);
                            }
                        } else {
                            $result->setSendStatus(Result::NotSent_LocalErrors);
                        }
                    } else {
                        $result->setSendStatus(Result::NotSent_EventInvoiceCompleted);
                    }
                } else {
                    $result->setSendStatus(Result::NotSent_EventInvoiceCreated);
                }
            } else {
                $result->setSendStatus(Result::NotSent_EmptyInvoice);
            }
        }

        return $result;
    }