private HtmlTableLine GetEmptyLine()
        {
            if (this.fakeSeperatorLine == null)
                this.fakeSeperatorLine = new HtmlTableLine();
            var line = this.fakeSeperatorLine;

            var id = this.fakeSeperatorCount++;
            line.Left.Id = id.ToString();
            line.Left.LineNum = id.ToString();
            line.Right.Id = id.ToString();
            line.Right.LineNum = id.ToString();
            return line;
        }
        /// <summary>
        ///     Generates the diff view for two file revisions.
        /// </summary>
        private string GenerateFileDiffView(
            int baseRevision, int diffRevision, UserSettingsDto settings,
            StreamCombiner baseFile, int baseId, string baseHeader,
            StreamCombiner diffFile, int diffId, string diffHeader,
            StreamCombiner rawDiff, string fileName, string outputFile)
        {
            var baseEncoder = GetEncoderForFile(fileName);
            var diffEncoder = GetEncoderForFile(fileName);

            var baseFileInfo = new DiffFileInfo(baseFile, baseEncoder, baseId, BaseOrDiff.Base);
            var diffFileInfo = new DiffFileInfo(diffFile, diffEncoder, diffId, BaseOrDiff.Diff);

            // Line Stamp format
            var baseScriptIdPrefix = "Base-" + EncodeLinePrefix(baseRevision, diffRevision, baseId, diffId, baseId);
            var diffScriptIdPrefix = "Diff-" + EncodeLinePrefix(baseRevision, diffRevision, baseId, diffId, diffId);
            var edgePrefix = "Edge-" + EncodeLinePrefix(baseRevision, diffRevision, baseId, diffId, diffId);
            var rowGroups = new List<HtmlTableRowGroup>();
            var lastBaseLine = "1";
            var lastDiffLine = "1";

            foreach (var diffItem in DiffItem.EnumerateDifferences(rawDiff))
            {
                var atEnd = diffItem.BaseLineCount == int.MaxValue;

                var baseLines = new List<Line>();
                for (var i = 0; i < diffItem.BaseLineCount && baseFileInfo.MoveNextLine(); ++i)
                    baseLines.Add(new Line
                        {
                            LineNum = baseFileInfo.CurLineNum.ToString(CultureInfo.InvariantCulture),
                            LineText = baseFileInfo.CurLine
                        });

                var diffLines = new List<Line>();
                for (var i = 0; i < diffItem.DiffLineCount && diffFileInfo.MoveNextLine(); ++i)
                    diffLines.Add(new Line
                        {
                            LineNum = diffFileInfo.CurLineNum.ToString(CultureInfo.InvariantCulture),
                            LineText = diffFileInfo.CurLine
                        });

                var baseLinesLength = baseLines.Count();
                var diffLinesLength = diffLines.Count();

                // The end is the only case where the DiffInfo line counts may be incorrect. If there are in fact
                // zero lines then just continue, which should cause the foreach block to end and we'll continue
                // like the DiffItem never existed.
                if (atEnd && diffItem.DiffType == DiffType.Unchanged && baseLinesLength == 0 && diffLinesLength == 0)
                    continue;

                var rowGroup = new HtmlTableRowGroup(diffItem.DiffType);

                for (var i = 0; i < Math.Max(baseLinesLength, diffLinesLength); ++i)
                {
                    var line = new HtmlTableLine();
                    if (i < baseLinesLength)
                    {
                        line.Left = baseLines[i];
                        line.Left.LineText = baseFileInfo.Encoder.EncodeLine(baseLines[i].LineText, int.MaxValue,
                                                                             TabValue);
                        lastBaseLine = line.Left.LineNum;
                    }
                    else
                    {
                        // new diff code - add entry for empty line with old line #
                        var idx = i - baseLinesLength;
                        line.Left = new Line { Id = lastBaseLine + '_' + idx };
                    }

                    if (i < diffLinesLength)
                    {
                        line.Right = diffLines[i];
                        line.Right.LineText = diffFileInfo.Encoder.EncodeLine(diffLines[i].LineText, int.MaxValue,
                                                                             TabValue);
                        lastDiffLine = line.Right.LineNum;
                    }
                    else
                    {
                        // new diff code - add entry for empty line with old line #
                        var idx = i - diffLinesLength;
                        line.Right = new Line { Id = lastDiffLine + '_' + idx };
                    }

                    rowGroup.Lines.Add(line);
                }

                if (diffItem.DiffType == DiffType.Changed)
                {
                    if (settings.diff.intraLineDiff)
                        InterlineDiff(rowGroup, settings.diff.ignoreWhiteSpace);
                }

                rowGroups.Add(rowGroup);
            }

            baseEncoder.Dispose();
            diffEncoder.Dispose();

            var htmlLines = EncodeRowGroups(rowGroups, baseHeader, diffHeader, baseScriptIdPrefix, diffScriptIdPrefix,
                                       edgePrefix);
            if (!string.IsNullOrWhiteSpace(outputFile))
            {
                var folder = Path.GetDirectoryName(outputFile);
                Directory.CreateDirectory(folder);
                File.WriteAllLines(outputFile, htmlLines);
                Log.Info("Generated {0}", outputFile);
                return outputFile;
            }
            else
            {
                return string.Join(Environment.NewLine, htmlLines);
            }
        }