public function waitAndLog(Activity $activity, $success = null, $failure = null)
    {
        $stdErr = $this->getStdErr();

        $stdErr->writeln(sprintf(
            'Waiting for the activity <info>%s</info> (%s):',
            $activity->id,
            self::getFormattedDescription($activity)
        ));

        // The progress bar will show elapsed time and the activity's state.
        $bar = $this->newProgressBar($stdErr);
        $bar->setPlaceholderFormatterDefinition('state', function () use ($activity) {
            return $this->formatState($activity->state);
        });
        $bar->setFormat('  [%bar%] %elapsed:6s% (%state%)');
        $bar->start();

        // Wait for the activity to complete.
        $activity->wait(
            // Advance the progress bar whenever the activity is polled.
            function () use ($bar) {
                $bar->advance();
            },
            // Display new log output when it is available.
            function ($log) use ($stdErr, $bar) {
                // Clear the progress bar and ensure the current line is flushed.
                $bar->clear();
                $stdErr->write($stdErr->isDecorated() ? "\n\033[1A" : "\n");

                // Display the new log output.
                $stdErr->write($this->indent($log));

                // Display the progress bar again.
                $bar->advance();
            }
        );
        $bar->finish();
        $stdErr->writeln('');

        // Display the success or failure messages.
        switch ($activity['result']) {
            case Activity::RESULT_SUCCESS:
                $stdErr->writeln($success ?: "Activity <info>{$activity->id}</info> succeeded");
                return true;

            case Activity::RESULT_FAILURE:
                $stdErr->writeln($failure ?: "Activity <error>{$activity->id}</error> failed");
                return false;
        }

        return false;
    }