async Task Search()
        {
            TestRunAttachmentsInfo.Clear();
            _cancelPending = false;
            SetTotalSize();
            Working = true;
            IEnumerable <ITestRun> runs     = TestQueryHelper.QueryRuns(NewerThan, OlderThan);
            IEnumerable <ISession> sessions = TestQueryHelper.QuerySessions(NewerThan, OlderThan);
            int numTotalRunsOrSessions      = runs.Count <ITestRun>() + sessions.Count <ISession>();

            if ((runs == null) || (!runs.Any()))
            {
                Trace.WriteLine("No test runs matched the time range specified.");
            }
            else
            {
                await ExecuteAttachmentCleanup(runs, TestObjectType.TestRun);
            }
            if ((sessions == null) || (!sessions.Any()))
            {
                Trace.WriteLine("No sessions matched the time range specified.");
            }
            else
            {
                await ExecuteAttachmentCleanup(sessions, TestObjectType.Session);
            }
            Working      = false;
            ProgressText = string.Format("Done");
        }
        private async Task ExecuteAttachmentCleanup(IEnumerable <ITestRunBase> runs, TestObjectType type)
        {
            int count = runs.Count <ITestRunBase>();

            ProgressText       = string.Format("Found {0} items of type {1}", count, type);
            ProgressTotalItems = count;
            ProgressValue      = 0;

            foreach (ITestRunBase run in runs)
            {
                if (IsCancelPending())
                {
                    break;
                }

                ProgressValue++;
                if (!this.MatchesDateRange(run))
                {
                    continue;
                }

                List <ITestAttachment> runAttachments = await GetRunAddtionalData(run, type);

                if (runAttachments == null || runAttachments.Count == 0)
                {
                    continue;
                }

                List <WorkItem> relatedWorkitems = await GetRelatedWorkItems(run, runAttachments);

                TestRunAttachmentsInfo.Add(new TestRunAttachmentInfo(run, type, runAttachments, relatedWorkitems));

                SetTotalSize();
            }
        }
        private void SetTotalSize()
        {
            var  wits     = TestRunAttachmentsInfo.SelectMany(w => w.RelatedWorkitems);
            long witSize  = wits.SelectMany(wit => wit.Attachments.Cast <Attachment>()).Sum(attachment => attachment.Length);
            long runsSize = TestRunAttachmentsInfo.SelectMany(a => a.MatchedAttachments).Sum(attachment => attachment.Length);

            TotalSize = string.Format(new FileSizeFormatProvider(), "{0:fs}", witSize + runsSize);
        }
        async Task Delete()
        {
            Working            = true;
            _cancelPending     = false;
            ProgressText       = string.Format("Deleting {0} items...", TestRunAttachmentsInfo.Count);
            ProgressTotalItems = TestRunAttachmentsInfo.Count;
            ProgressValue      = 0;

            await Task.Run(() =>
            {
                var itemsToDelete = TestRunAttachmentsInfo.ToList();
                foreach (TestRunAttachmentInfo itemAttachmentInfo in itemsToDelete)
                {
                    if (IsCancelPending())
                    {
                        break;
                    }

                    IAttachmentOwner owner = itemAttachmentInfo.Run;
                    for (var i = 0; i < owner.Attachments.Count; i++)
                    {
                        if (IsCancelPending())
                        {
                            break;
                        }

                        var attachment = owner.Attachments[i];
                        if (!itemAttachmentInfo.MatchedAttachments.Contains(attachment))
                        {
                            continue;
                        }

                        owner.Attachments.RemoveAt(i);
                        itemAttachmentInfo.MatchedAttachments.Remove(attachment);
                    }
                    itemAttachmentInfo.Run.Save();


                    foreach (var wit in itemAttachmentInfo.RelatedWorkitems)
                    {
                        wit.Attachments.Clear();
                        wit.Save();
                    }

                    ProgressValue++;
                    SetTotalSize();
                }
            });

            ProgressText = "Done";
            TestRunAttachmentsInfo.Clear();
            Working = false;
            return;
        }