public void Finish(FinishLaunchRequest request)
        {
            TraceLogger.Verbose($"Scheduling request to finish launch in {GetHashCode()} proxy instance");

            if (StartTask == null)
            {
                throw new InsufficientExecutionStackException("The launch wasn't scheduled for starting to finish it properly.");
            }

            if (FinishTask != null)
            {
                throw new InsufficientExecutionStackException("The launch is already scheduled for finishing.");
            }

            var dependentTasks = new List <Task>();

            if (ChildTestReporters != null)
            {
                dependentTasks.AddRange(ChildTestReporters.Select(tn => tn.FinishTask));
            }
            dependentTasks.Add(StartTask);

            FinishTask = Task.Factory.ContinueWhenAll(dependentTasks.ToArray(), async(dts) =>
            {
                try
                {
                    if (StartTask.IsFaulted)
                    {
                        throw new Exception("Cannot finish launch due starting launch failed.", StartTask.Exception);
                    }

                    if (ChildTestReporters?.Any(ctr => ctr.FinishTask.IsFaulted) == true)
                    {
                        throw new AggregateException("Cannot finish launch due inner items failed to finish.", ChildTestReporters.Where(ctr => ctr.FinishTask.IsFaulted).Select(ctr => ctr.FinishTask.Exception).ToArray());
                    }

                    if (request.EndTime < LaunchInfo.StartTime)
                    {
                        request.EndTime = LaunchInfo.StartTime;
                    }

                    if (!_isExternalLaunchId)
                    {
                        await _service.FinishLaunchAsync(LaunchInfo.Id, request);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    // clean childs
                    ChildTestReporters = null;
                }
            }).Unwrap();
        }
        public void Finish(FinishTestItemRequest request)
        {
            TraceLogger.Verbose("Scheduling request to finish new test item");

            if (StartTask == null)
            {
                throw new InsufficientExecutionStackException("The test item wasn't scheduled for starting to finish it properly.");
            }

            if (FinishTask != null)
            {
                throw new InsufficientExecutionStackException("The test item is already scheduled for finishing.");
            }

            var dependentTasks = new List <Task>();

            dependentTasks.Add(StartTask);
            if (_additionalTasks != null)
            {
                dependentTasks.AddRange(_additionalTasks);
            }
            if (ChildTestReporters != null)
            {
                dependentTasks.AddRange(ChildTestReporters.Select(tn => tn.FinishTask));
            }

            FinishTask = Task.Factory.ContinueWhenAll(dependentTasks.ToArray(), async(a) =>
            {
                try
                {
                    if (StartTask.IsFaulted)
                    {
                        throw new Exception("Cannot finish test item due starting item failed.", StartTask.Exception);
                    }

                    if (ChildTestReporters?.Any(ctr => ctr.FinishTask.IsFaulted) == true)
                    {
                        throw new AggregateException("Cannot finish test item due finishing of child items failed.", ChildTestReporters.Where(ctr => ctr.FinishTask.IsFaulted).Select(ctr => ctr.FinishTask.Exception).ToArray());
                    }

                    TestInfo.EndTime = request.EndTime;
                    TestInfo.Status  = request.Status;

                    if (request.EndTime < TestInfo.StartTime)
                    {
                        request.EndTime = TestInfo.StartTime;
                    }

                    await _service.FinishTestItemAsync(TestInfo.Id, request);
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    // clean up childs
                    ChildTestReporters = null;

                    // clean up addition tasks
                    _additionalTasks = null;
                }
            }).Unwrap();
        }