public function generateTextBody(ComposerEvent $event)
    {
        $parts = $event->getBody()->getParts();

        $htmlBody = null;
        $htmlPart = null;
        $textBody = null;

        // locate HTML body
        foreach ($parts as $part) {
            foreach ($part->getHeadersArray() as $header) {
                if ($header[0] == 'Content-Type' && strpos($header[1], 'text/html') === 0) {
                    $htmlPart = $part;
                    $htmlBody = $part->getRawContent();
                } elseif ($header[0] == 'Content-Type' && strpos($header[1], 'text/plain') === 0) {
                    $textBody = $part->getRawContent();
                }
            }
        }

        if ($textBody || !$htmlBody) {
            // can only work if HTML body exists and text doesn't
            return;
        }

        // create and insert text body
        $textBody = strip_tags($this->br2nl($htmlBody));
        $textPart = new MimePart($textBody);
        $textPart->type = 'text/plain';
        $event->getBody()->setParts([$textPart, $htmlPart]);

        // force multipart/alternative content type
        $event->getMessage()->getHeaders()->get('content-type')->setType('multipart/alternative')
            ->addParameter('boundary', $event->getBody()->getMime()->boundary());
    }