public override async Task <Dictionary <BenchmarkResult, BenchmarkResult> > TryUpdateStatus(IEnumerable <BenchmarkResult> toModify, ResultStatus status)
        {
            if (toModify == null)
            {
                throw new ArgumentNullException(nameof(toModify));
            }

            var mod = new Dictionary <BenchmarkResult, BenchmarkResult>();

            foreach (var oldRes in toModify)
            {
                mod.Add(oldRes, null);
            }
            if (mod.Count == 0)
            {
                return(mod);
            }

            int n                  = Benchmarks.Length;
            var newBenchmarks      = (BenchmarkResult[])Benchmarks.Clone();
            var newAzureBenchmarks = new AzureBenchmarkResult[n];

            for (int i = 0; i < n; i++)
            {
                var b = newBenchmarks[i];
                AzureBenchmarkResult azureResult;

                if (mod.ContainsKey(b))
                {
                    if (b.Status != status) // updating status of this result
                    {
                        newBenchmarks[i] = new BenchmarkResult(b.ExperimentID, b.BenchmarkFileName,
                                                               b.AcquireTime, b.NormalizedCPUTime, b.CPUTime, b.WallClockTime,
                                                               b.PeakMemorySizeMB,
                                                               status, // <-- new status
                                                               b.ExitCode, b.StdOut, b.StdErr, b.Properties);

                        azureResult = ToAzureResult(newBenchmarks[i], TryGetExternalOutput(b));
                        mod[b]      = newBenchmarks[i];
                    }
                    else // status is as required already
                    {
                        azureResult = ToAzureResult(b, TryGetExternalOutput(b));
                        mod.Remove(b);
                    }
                }
                else // result doesn't change
                {
                    azureResult = ToAzureResult(b, TryGetExternalOutput(b));
                }

                newAzureBenchmarks[i] = azureResult;
            }

            if (mod.Count == 0)
            {
                return(new Dictionary <BenchmarkResult, BenchmarkResult>());               // no changes
            }
            foreach (var item in mod)
            {
                if (item.Value == null)
                {
                    throw new ArgumentException("Some of the given results to update do not belong to the experiment results");
                }
            }

            string newEtag = await Upload(newAzureBenchmarks);

            if (newEtag == null)
            {
                return(null);
            }

            // Update benchmarks array
            etag = newEtag;
            Replace(newBenchmarks.ToArray());
            foreach (var item in externalOutputs.ToArray())
            {
                BenchmarkResult oldB = item.Key;
                BenchmarkResult newB;
                if (!mod.TryGetValue(oldB, out newB))
                {
                    continue;
                }

                AzureBenchmarkResult ar;
                if (externalOutputs.TryGetValue(oldB, out ar))
                {
                    externalOutputs.Remove(oldB);
                    externalOutputs.Add(newB, ar);
                }
            }

            return(mod);
        }
        public override async Task <Dictionary <BenchmarkResult, BenchmarkResult> > TryUpdateStatus(IEnumerable <BenchmarkResult> toModify, ResultStatus status)
        {
            if (toModify == null)
            {
                throw new ArgumentNullException(nameof(toModify));
            }

            var mod = new Dictionary <BenchmarkResult, BenchmarkResult>();

            foreach (var oldRes in toModify)
            {
                mod.Add(oldRes, null);
            }
            if (mod.Count == 0)
            {
                return(mod);
            }

            int n                  = Benchmarks.Length;
            var newBenchmarks      = (BenchmarkResult[])Benchmarks.Clone();
            var newAzureBenchmarks = new AzureBenchmarkResult[n];

            for (int i = 0; i < n; i++)
            {
                var b = newBenchmarks[i];

                if (mod.ContainsKey(b))
                {
                    if (b.Status != status) // updating status of this result
                    {
                        newBenchmarks[i] = new BenchmarkResult(b.ExperimentID, b.BenchmarkFileName,
                                                               b.AcquireTime, b.NormalizedRuntime, b.TotalProcessorTime, b.WallClockTime,
                                                               b.PeakMemorySizeMB,
                                                               status, // <-- new status
                                                               b.ExitCode, b.StdOut, b.StdErr, b.Properties);

                        newAzureBenchmarks[i] = AzureExperimentStorage.ToAzureBenchmarkResult(newBenchmarks[i]);

                        mod[b] = newBenchmarks[i];
                    }
                    else // status is as required already
                    {
                        newAzureBenchmarks[i] = AzureExperimentStorage.ToAzureBenchmarkResult(b);
                        mod.Remove(b);
                    }
                }
                else // result doesn't change
                {
                    newAzureBenchmarks[i] = AzureExperimentStorage.ToAzureBenchmarkResult(b);
                }
            }

            if (mod.Count == 0)
            {
                return(new Dictionary <BenchmarkResult, BenchmarkResult>());               // no changes
            }
            foreach (var item in mod)
            {
                if (item.Value == null)
                {
                    throw new ArgumentException("Some of the given results to update do not belong to the experiment results");
                }
            }

            bool success = await Upload(newAzureBenchmarks);

            if (!success)
            {
                return(null);
            }

            // Update benchmarks array
            Replace(newBenchmarks.ToArray());

            return(mod);
        }