public static void DiffRevision(int id, int fileId, int revisionId, bool force)
        {
            var changeList = GetChangeList(id);
            var changeFile = GetChangeFile(changeList, fileId);

            var gen = new DiffGenerator(db);
            var baseReviewId = gen.GetBaseReviewId(UserName.userName, changeList.Id);
            var fileVersions = changeFile.FileVersions.ToArray();
            var prev = 0;
            for (var idx = prev + 1; idx < fileVersions.Length; prev = idx++)
            {
                if (revisionId != idx - 1)
                    continue;

                var vid1 = fileVersions[prev].Id;
                var vid2 = fileVersions[idx].Id;
                var left = fileVersions[prev];
                var right = fileVersions[idx];

                var diffFile = gen.GenerateDiffFile(left, right, changeList.CL, baseReviewId, UserSettings, force);
                if (string.IsNullOrEmpty(diffFile) || !System.IO.File.Exists(diffFile))
                    throw new ApplicationException(string.Format("Failed to create a diff file for change list id: {0} file id: {1} revision id: {2}", id, fileId, revisionId));

                Console.WriteLine("Generated {0}", diffFile);
                return;
            }

            throw new ApplicationException(string.Format("Did not find revision for change list id: {0} file id: {1} revision id: {2}", id, fileId, revisionId));
        }
        static void Main(string[] args)
        {
            Log.ConsoleMode = true;

            int id = 0;
            var changeFiles = new List<ChangeFile>();

            var options = new GenDiffArgs();
            if (Parser.ParseArgumentsWithUsage(args, options))
            {
                if (!string.IsNullOrEmpty(options.CL))
                {
                    //     insert application code here
                    var changeList = (from change in db.ChangeLists
                                      where change.CL == options.CL
                                      select change).FirstOrDefault();
                    if (changeList != null)
                        id = changeList.Id;
                }

                if (!string.IsNullOrEmpty(options.file))
                {
                    var fileName = options.file.ToLower();
                    var files = (from file in db.ChangeFiles
                                       where file.ServerFileName.ToLower().Contains(fileName) &&
                                            (id == 0 || file.ChangeListId == id)
                                       select file);
                    foreach (var file in files)
                    {
                        changeFiles.Add(file);
                    }
                }

                if (options.fileId > 0 && options.revisionId < 0)
                {
                    var fileName = options.file.ToLower();
                    var files = (from file in db.ChangeFiles
                                 where file.Id == options.fileId &&
                                      (id == 0 || file.ChangeListId == id)
                                 select file);
                    foreach (var file in files)
                    {
                        changeFiles.Add(file);
                    }
                }
            }

            var userName = Environment.GetEnvironmentVariable("USERNAME").Trim();
            UserName = new UserName(userName, db);
            UserSettings = ReviewUtil.UserSettings(0, UserName.userName, db);

            if (changeFiles.Count > 0)
            {
                foreach (var changeFile in changeFiles)
                {
                    DiffRevision(changeFile.ChangeListId, changeFile.Id, changeFile.ReviewRevision - 1, force);
                }
            }
            else if (id != 0)
            {
                if (options.fileId != 0 && options.revisionId >= 0)
                {
                    DiffRevision(id, options.fileId, options.revisionId, force);
                }
                else
                {
                    var gen = new DiffGenerator(db);
                    gen.GenDiffFiles(id, UserName.userName, UserSettings, force);
                }
            }
            else
            {
                var gen = new DiffGenerator(db);

                var changelists = (from item in db.ChangeLists.AsNoTracking()
                                   where (item.Stage != (int)ChangeListStatus.Deleted)
                                   select item).OrderByDescending(x => x.TimeStamp);
                foreach (var item in changelists)
                {
                    Log.Info("Generate diff files for {0} {1}", item.CL, item.Id);
                    gen.GenDiffFiles(item.Id, UserName.userName, UserSettings, force);
                }
            }
        }