public static function generate($before, $after)
    {
        if ($before === $after) {
            return '';
        }

        if (strlen($before) > self::MAX_SIZE || strlen($after) > self::MAX_SIZE) {
            return '';
        }

        $beforeTmpFile = tempnam(sys_get_temp_dir(), 'diff');
        file_put_contents($beforeTmpFile, $before);

        $afterTmpFile = tempnam(sys_get_temp_dir(), 'diff');
        file_put_contents($afterTmpFile, $after);

        $proc = new Process('git diff --no-index --exit-code -- '.escapeshellarg($beforeTmpFile).' '.escapeshellarg($afterTmpFile));
        $proc->run();

        @unlink($beforeTmpFile);
        @unlink($afterTmpFile);

        switch ($proc->getExitCode()) {
            // $before and $after were deemed identical. Should normally never
            // be reached as we already check for this above.
            case 0:
                return '';

            // The first four lines contain information about the files which were being compared.
            // We can savely trim them as we only generate the diff for one file.
            case 1:
                $output = explode("\n", $proc->getOutput());

                return implode("\n", array_slice($output, 4));

            default:
                throw new ProcessFailedException($proc);
        }
    }