internal static Result PostCheckinStage(
                IRestApi restApi,
                Branch branch,
                MergeReport mergeReport,
                string taskNumber,
                string[] destinationBranches,
                MergeToOperations.CheckinResult mergesToCheckins,
                MultilinerBotConfiguration botConfig,
                string codeReviewsStorageFile)
            {
                if (!HasToRunPlanAfterTaskMerged(botConfig.CI))
                {
                    string noCIMessage =
                        "No Continuous Integration Plug was set for this mergebot. Therefore, no " +
                        "build actions for task " + taskNumber + " will be performed.";

                    mLog.Info(noCIMessage);

                    return(Result.Ok);
                }

                if (mergesToCheckins == null ||
                    mergesToCheckins.ChangesetsByTargetBranch == null ||
                    mergesToCheckins.ChangesetsByTargetBranch.Count == 0)
                {
                    string noChangesetsErrorMessage = string.Format(
                        "Something wrong happened. There are no merge-to changesets to build after " +
                        "merging branch [{0}] to its destination branches.", branch.FullName);

                    mLog.Info(noChangesetsErrorMessage);

                    Notifier.NotifyTaskStatus(
                        restApi, branch.Owner, noChangesetsErrorMessage, botConfig.Notifiers);

                    return(Result.Failed);
                }

                string startTestingMessage = string.Format(
                    "Testing branch [{0}] after being merged in the following destination branches: [{1}].",
                    branch.FullName,
                    string.Join(", ", mergesToCheckins.ChangesetsByTargetBranch.Keys));

                mLog.Info(startTestingMessage);

                Notifier.NotifyTaskStatus(
                    restApi, branch.Owner, startTestingMessage, botConfig.Notifiers);

                int iniTime = Environment.TickCount;

                BuildOperations.Result result = BuildOperations.TryBuildTask(
                    restApi,
                    branch,
                    mergeReport,
                    taskNumber,
                    destinationBranches,
                    mergesToCheckins.ChangesetsByTargetBranch,
                    Messages.BuildProperties.StageValues.POST_CHECKIN,
                    botConfig);

                BuildMergeReport.AddBuildTimeProperty(
                    mergeReport, Environment.TickCount - iniTime);

                if (result.AreAllSuccessful)
                {
                    BuildMergeReport.AddSucceededBuildProperty(
                        mergeReport, botConfig.CI.PlanAfterCheckin);

                    string notifyOKMesage = string.Format(
                        "Build successful after merging branch [{0}] " +
                        "to the following destination branches: [{1}].",
                        branch.FullName,
                        string.Join(", ", mergesToCheckins.ChangesetsByTargetBranch.Keys));

                    Notifier.NotifyTaskStatus(
                        restApi, branch.Owner, notifyOKMesage, botConfig.Notifiers);

                    return(Result.Ok);
                }

                string errorMessage = string.Join(Environment.NewLine, result.ErrorMessages);

                BuildMergeReport.AddFailedBuildProperty(
                    mergeReport, botConfig.CI.PlanAfterCheckin, errorMessage);

                Notifier.NotifyTaskStatus(
                    restApi, branch.Owner, errorMessage, botConfig.Notifiers);

                return(Result.Failed);
            }
            internal static bool PreCheckinStage(
                IRestApi restApi,
                Branch branch,
                MergeReport mergeReport,
                string taskNumber,
                string[] destinationBranches,
                MergeToOperations.ShelveResult mergesToShelves,
                MultilinerBotConfiguration botConfig,
                string codeReviewsStorageFile)
            {
                if (botConfig.CI == null)
                {
                    string noCIMessage =
                        "No Continuous Integration Plug was set for this mergebot. Therefore, no " +
                        "build actions for task " + taskNumber + " will be performed.";

                    mLog.Info(noCIMessage);

                    Notifier.NotifyTaskStatus(
                        restApi, branch.Owner, noCIMessage, botConfig.Notifiers);

                    return(true);
                }

                if (mergesToShelves == null ||
                    mergesToShelves.ShelvesByTargetBranch == null ||
                    mergesToShelves.ShelvesByTargetBranch.Count == 0)
                {
                    string noShelvesErrorMessage =
                        "Something wrong happened. There are no merge-to shelves to build task " + taskNumber;

                    mLog.Info(noShelvesErrorMessage);

                    Notifier.NotifyTaskStatus(
                        restApi, branch.Owner, noShelvesErrorMessage, botConfig.Notifiers);

                    ChangeTaskStatus.SetTaskAsFailed(
                        restApi, branch, taskNumber, botConfig, codeReviewsStorageFile);

                    return(false);
                }

                string startTestingMessage = string.Format(
                    "Testing branch [{0}] before being merged in the following destination branches: [{1}].",
                    branch.FullName,
                    string.Join(", ", mergesToShelves.ShelvesByTargetBranch.Keys));

                mLog.Info(startTestingMessage);

                ChangeTaskStatus.SetTaskAsTesting(restApi, branch, taskNumber, botConfig);

                Notifier.NotifyTaskStatus(
                    restApi, branch.Owner, startTestingMessage, botConfig.Notifiers);

                int iniTime = Environment.TickCount;

                BuildOperations.Result result = BuildOperations.TryBuildTask(
                    restApi,
                    branch,
                    mergeReport,
                    taskNumber,
                    destinationBranches,
                    mergesToShelves.ShelvesByTargetBranch,
                    Messages.BuildProperties.StageValues.PRE_CHECKIN,
                    botConfig);

                BuildMergeReport.AddBuildTimeProperty(
                    mergeReport, Environment.TickCount - iniTime);

                if (result.AreAllSuccessful)
                {
                    BuildMergeReport.AddSucceededBuildProperty(
                        mergeReport, botConfig.CI.PlanBranch);

                    return(true);
                }

                string errorMessage = string.Join(Environment.NewLine, result.ErrorMessages);

                BuildMergeReport.AddFailedBuildProperty(
                    mergeReport, botConfig.CI.PlanBranch, errorMessage);

                ChangeTaskStatus.SetTaskAsFailed(
                    restApi, branch, taskNumber, botConfig, codeReviewsStorageFile);

                Notifier.NotifyTaskStatus(
                    restApi, branch.Owner, errorMessage, botConfig.Notifiers);

                return(false);
            }