public StepTiming GetPipelineTiming(string pipeline)
        {
            var pipelineInfo = _goRequest.GetPipelineInfo(pipeline);
            if (pipelineInfo.Groups.Count == 0 || pipelineInfo.Groups[0].History.Count == 0)
                return null;

            var lastHistroy = pipelineInfo.Groups[0].History[0];

            var stageTimings = new List<StepTiming>();

            var pipelinePeriodCalc = new TimePeriodCaluclator();

            foreach (var stageItem in lastHistroy.Stages)
            {
                var stageTiming = GetStageTiming(pipeline, stageItem);
                if (stageTiming == null) continue;

                pipelinePeriodCalc.AddPeriod(stageTiming.StartTime, stageTiming.FinishTime);

                stageTimings.Add(stageTiming);
            }

            int buildNumber;
            var hasBuildNumber = int.TryParse(lastHistroy.CounterOrLabel, out buildNumber);
            return new StepTiming
            {
                StepName = pipeline,
                Locator = null,
                StepId = lastHistroy.PipelineId,
                StartTime = pipelinePeriodCalc.StartTime.ToUniversalTime(),
                FinishTime = pipelinePeriodCalc.FinishTime.ToUniversalTime(),
                ChildSteps = stageTimings,
                BuildNumber = hasBuildNumber ? buildNumber : (int?)null
            };
        }
        private StepTiming GetStageTiming(string pipeline, Stage stage)
        {
            if (stage.StageId == "0")
            {
                Log.WarnFormat("Stage doesn't has actual state. Stage={0}", stage);
                return null;
            }

            var jobIds = _goRequest.GetJobsForStage(stage.StageId);

            var jobTimings = new List<StepTiming>();

            var stagePeriodCalc = new TimePeriodCaluclator();

            foreach (var jobId in jobIds)
            {
                var jobTiming = GetJobTiming(pipeline, stage.StageName, jobId);
                if (jobTiming == null) continue;

                stagePeriodCalc.AddPeriod(jobTiming.StartTime, jobTiming.FinishTime);

                jobTimings.Add(jobTiming);
            }

            return new StepTiming
            {
                StepName = stage.StageName,
                Locator = string.Format("{0}pipelines/{1}", _goRequest.BaseUrl, stage.StageLocator),
                StepId = stage.StageId,
                StartTime = stagePeriodCalc.StartTime.ToUniversalTime(),
                FinishTime = stagePeriodCalc.FinishTime.ToUniversalTime(),
                ChildSteps = jobTimings
            };
        }