public override string ReadLine()
        {
            const int ChangesetTimeMilliseconds = 3000;

            if (m_vcs == null)
            {
                Connect();
            }

            if (m_latestChangesetId == 0)
            {
                // First run. Searching latest changeset
                var latestChangeset = GetLatestChangeset();
                if (latestChangeset == null)
                {
                    return(null); // No any chanesets found!
                }
                foreach (var line in m_changesetConverter.GetLogLines(latestChangeset))
                {
                    m_latestChanges.Enqueue(line);
                }

                // How mutch a wait before get next line
                m_waitMilliseconds = m_latestChanges.Count > 0 ? ChangesetTimeMilliseconds / m_latestChanges.Count : 0;

                m_latestChangesetId = latestChangeset.ChangesetId;
            }
            else
            {
                if (m_latestChanges.Count == 0)
                {
                    // Getting new changes after latest previous changeset Id
                    var foundChanges = FindLatestChanges(m_latestChangesetId);
                    if (foundChanges != null)
                    {
                        foreach (var changeset in foundChanges)
                        {
                            foreach (var line in m_changesetConverter.GetLogLines(changeset))
                            {
                                m_latestChanges.Enqueue(line);
                            }

                            m_latestChangesetId = changeset.ChangesetId;
                        }
                    }

                    // How mutch a wait before get next line
                    m_waitMilliseconds = m_latestChanges.Count > 0 ? ChangesetTimeMilliseconds / m_latestChanges.Count : 0;
                }
            }

            if (m_latestChanges.Count == 0)
            {
                return(null);
            }

            // Simulate changes time to avoid super fast
            var sleepTime = m_waitMilliseconds - (Environment.TickCount - m_lastReadLineTicks);

            if (sleepTime > 0 && sleepTime <= m_waitMilliseconds)
            {
                System.Diagnostics.Debug.WriteLine("WAIT: " + sleepTime);
                System.Threading.Thread.Sleep(sleepTime);
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("WAIT: none");
            }
            m_lastReadLineTicks = Environment.TickCount;

            return(m_latestChanges.Dequeue());
        }
        private static bool CreateGourceLogFile(
            string outputFile,
            HashSet <string> outputCommiters,
            VersionControlServer vcs,
            string serverPath,
            VisualizationSettings settings,
            ref bool cancel,
            Action <int> progressReporter)
        {
//			int latestChangesetId = vcs.GetLatestChangesetId();
            if (cancel)
            {
                return(false);
            }

            var versionFrom = new DateVersionSpec(settings.DateFrom);
            var versionTo   = new DateVersionSpec(settings.DateTo);

            int latestChangesetId;
            // Getting latest changeset ID for current search criteria
            {
                var latestChanges = vcs.QueryHistory(
                    serverPath,
                    VersionSpec.Latest,
                    0,
                    RecursionType.Full,
                    null,        //any user
                    versionFrom, // from first changeset
                    versionTo,   // to last changeset
                    1,
                    false,       // with changes
                    false,
                    false,
                    false); // sorted

                var latestChangeset = latestChanges.Cast <Changeset>().FirstOrDefault();
                if (latestChangeset == null)
                {
                    // History not found
                    return(false);
                }
                latestChangesetId = latestChangeset.ChangesetId;
                if (cancel)
                {
                    return(false);        //-V3022
                }
            }

            var firstChangesetId = 0;

            var changesetConverter = new ChangesetConverter(settings.UsersFilter, settings.FilesFilter);

            using (var writer = new StreamWriter(outputFile))
            {
                var csList = vcs.QueryHistory(
                    serverPath,
                    VersionSpec.Latest,
                    0,
                    RecursionType.Full,
                    null,        //any user
                    versionFrom, // from first changeset
                    versionTo,   // to last changeset
                    int.MaxValue,
                    true,        // with changes
                    false,
                    false,
                    true);                     // sorted

                var hasLines = false;

                foreach (var changeset in csList.Cast <Changeset>())
                {
                    if (cancel)
                    {
                        return(false);        //-V3022
                    }
                    if (firstChangesetId == 0)
                    {
                        firstChangesetId = changeset.ChangesetId;
                    }

                    if (progressReporter != null)
                    {
                        var progressValue = changeset.ChangesetId - firstChangesetId;
                        var progressTotal = latestChangesetId - firstChangesetId;

                        progressReporter(progressTotal > 0 ? progressValue * 100 / progressTotal : 100);
                    }

                    var usefulChangeset = false;
                    foreach (var line in changesetConverter.GetLogLines(changeset))
                    {
                        usefulChangeset = true;
                        writer.WriteLine(line);
                    }

                    if (usefulChangeset)
                    {
                        hasLines = true;
                        if (outputCommiters != null)
                        {
                            outputCommiters.Add(changeset.OwnerDisplayName);
                        }
                    }
                }

                return(hasLines);
            }
        }