private void InitializeEditViewModel(EditViewModel viewModel, GMailLabelCleanup.Data.Models.Filters.Filter filter)
        {
            System.Diagnostics.Debug.Assert(viewModel != null);

            viewModel.Id          = filter != null ? filter.FilterId : 0;
            viewModel.Description = filter != null ? filter.Description : string.Empty;

            InitializeEditSelectLists(viewModel);
            InitializeEditProperties(viewModel, filter != null ? filter.FilterProperties : new FilterProperty[] { });
        }
        private bool ApplyEdits(EditViewModel viewModel, GMailLabelCleanup.Data.Models.Filters.Filter filter)
        {
            System.Diagnostics.Debug.Assert(viewModel != null);
            System.Diagnostics.Debug.Assert(filter != null);

            bool hasChanges = false;

            //Apply high level properties
            if (!string.Equals(filter.Description, viewModel.Description))
            {
                filter.Description = viewModel.Description;
                hasChanges         = true;
            }

            foreach (var item in viewModel.ActionProperties.Concat(viewModel.CriteriaProperties).Where(o => o.IsCheckType))
            {
                item.Value = item.IsChecked ? "true" : "false";
            }

            /*
             * New properties:
             * ViewModel properties that are included and whose
             * name does not appear in the Filter.FilterProperties.
             *
             * Updated properies:
             * ViewModel properties whose
             * name appears in the Filter.FilterProperties.
             */

            var existingPropertyNames = filter.FilterProperties
                                        .Select(o => o.Name)
                                        .ToHashSet();

            var allProperties = viewModel.CriteriaProperties
                                .Concat(viewModel.ActionProperties)
                                .ToArray();

            var newProperties = allProperties
                                .Where(o => !existingPropertyNames.Contains(o.Name));
            var updatedProperties = allProperties
                                    .Where(o => existingPropertyNames.Contains(o.Name));

            var dateCreated = DateTime.UtcNow;

            foreach (var item in updatedProperties)
            {
                var matches = filter.FilterProperties
                              .Where(o => string.Equals(o.Name, item.Name) && (!string.Equals(o.Value, item.Value) || o.IsIncluded != item.IsIncluded))
                              .ToArray();

                foreach (var match in matches)
                {
                    match.IsIncluded = item.IsIncluded;
                    match.Value      = item.Value;
                    hasChanges       = true;
                }
            }
            foreach (var item in newProperties)
            {
                filter.FilterProperties.Add(new FilterProperty
                {
                    IsIncluded     = item.IsIncluded,
                    Name           = item.Name,
                    Value          = item.Value,
                    DateCreatedUtc = dateCreated
                });
                hasChanges = true;
            }
            return(hasChanges);
        }
        private async Task <ActionResult> EditPostCore(EditViewModel viewModel)
        {
            System.Diagnostics.Debug.Assert(viewModel != null);

            ValidateProperties(viewModel);
            if (!ModelState.IsValid)
            {
                InitializeEditSelectLists(viewModel);
                return(View(viewModel));
            }

            var userId  = GetUserId();
            var context = this.DbContext;

            var isNew = viewModel.Id == 0;

            GMailLabelCleanup.Data.Models.Filters.Filter filter;
            if (!isNew)
            {
                filter = await context.Filters
                         .Include(o => o.FilterProperties)
                         .Where(o => o.FilterId == viewModel.Id && o.UserId == userId)
                         .FirstOrDefaultAsync();

                if (filter == null)
                {
                    return(HttpNotFound("Could not find filter."));
                }
            }
            else
            {
                filter = new GMailLabelCleanup.Data.Models.Filters.Filter
                {
                    UserId           = userId,
                    DateCreatedUtc   = DateTime.UtcNow,
                    Description      = viewModel.Description,
                    FilterProperties = new List <FilterProperty>()
                };
            }

            if (isNew)
            {
                context.Filters.Add(filter);
            }

            if (ApplyEdits(viewModel, filter) || isNew)
            {
                await context.SaveChangesAsync();

                if (isNew)
                {
                    await Task.Run(() => new TelemetryClient().TrackEvent("CreateFilter"));
                }
                else
                {
                    await Task.Run(() => new TelemetryClient().TrackEvent("EditFilter"));
                }
            }

            return(RedirectToAction("Index"));
        }
        private async Task<ActionResult> EditPostCore(EditViewModel viewModel)
        {
            System.Diagnostics.Debug.Assert(viewModel != null);

            ValidateProperties(viewModel);
            if (!ModelState.IsValid)
            {
                InitializeEditSelectLists(viewModel);
                return View(viewModel);
            }

            var userId = GetUserId();
            var context = this.DbContext;

            var isNew = viewModel.Id == 0;

            GMailLabelCleanup.Data.Models.Filters.Filter filter;
            if (!isNew)
            {
                filter = await context.Filters
                    .Include(o => o.FilterProperties)
                    .Where(o => o.FilterId == viewModel.Id && o.UserId == userId)
                    .FirstOrDefaultAsync();

                if (filter == null)
                    return HttpNotFound("Could not find filter.");
            }
            else
            {
                filter = new GMailLabelCleanup.Data.Models.Filters.Filter
                {
                    UserId = userId,
                    DateCreatedUtc = DateTime.UtcNow,
                    Description = viewModel.Description,
                    FilterProperties = new List<FilterProperty>()
                };
            }

            if (isNew)
            {
                context.Filters.Add(filter);
            }

            if (ApplyEdits(viewModel, filter) || isNew)
            {
                await context.SaveChangesAsync();

                if (isNew)
                {
                    await Task.Run(() => new TelemetryClient().TrackEvent("CreateFilter"));
                }
                else
                {
                    await Task.Run(() => new TelemetryClient().TrackEvent("EditFilter"));
                }
            }

            return RedirectToAction("Index");
        }