private static async Task __SetOneSelectionToAnother(
            NtwkDBContext context,
            int profileId,
            ProfileSelectedTagFlags from,
            ProfileSelectedTagFlags to
            )
        {
            IEnumerable <ProfileSelectedTag> fromAndToSelections =
                await context.ProfilesTagSelection
                .Where(pst => pst.BindedProfileID == profileId &&
                       (
                           from == (pst.Flags & from) ||
                           to == (pst.Flags & to))
                       )
                .ToListAsync();

            IEnumerable <ProfileSelectedTag> toSet = fromAndToSelections
                                                     .Where(pst => from == (pst.Flags & from) &&
                                                            to != (pst.Flags & to));
            IEnumerable <ProfileSelectedTag> toRemove = fromAndToSelections
                                                        .Where(pst => ProfileSelectedTagFlags.None == (pst.Flags ^ to));

            foreach (ProfileSelectedTag pst in toSet)
            {
                pst.Flags = pst.Flags | to;
            }

            context.ProfilesTagSelection.RemoveRange(toRemove);
            await context.SaveChangesAsync();
        }
        private static async Task __SetProfileTagSelection(
            NtwkDBContext context,
            int profileId,
            IEnumerable <int> tagIDs,
            ProfileSelectedTagFlags flag
            )
        {
            IEnumerable <int> ids = tagIDs as int[] ?? tagIDs.ToArray();
            IEnumerable <ProfileSelectedTag> currentSelection =
                await context.ProfilesTagSelection
                .Where(pts => pts.BindedProfileID == profileId)
                .ToListAsync();

            var currentWithFlag = currentSelection
                                  .Where(pts => flag == (pts.Flags & flag))
                                  .Select(pts => new
            {
                toStay = ids.Contains(pts.TagID),
                pts
            })
                                  .GroupBy(t => t.toStay)
                                  .Select(collection => new
            {
                collection.First().toStay,
                col = collection.Select(t => t.pts)
            })
                                  .ToArray();
            IEnumerable <int> toStay = currentWithFlag
                                       .SingleOrDefault(t => t.toStay)
                                       ?.col?.Select(pst => pst.TagID).ToList();
            IEnumerable <ProfileSelectedTag> toReset = currentWithFlag
                                                       .SingleOrDefault(t => !t.toStay)
                                                       ?.col;

            toStay  = toStay ?? (new List <int>());
            toReset = toReset ?? (new List <ProfileSelectedTag>());
            IEnumerable <ProfileSelectedTag> currentWithoutFlagToSet =
                currentSelection
                .Where(pts => flag != (pts.Flags & flag))
                .Where(pts => ids.Contains(pts.TagID))
                .ToList();

            foreach (ProfileSelectedTag pst in currentWithoutFlagToSet)
            {
                pst.Flags = pst.Flags | flag;
            }

            List <ProfileSelectedTag> toRemove = new List <ProfileSelectedTag>();

            foreach (ProfileSelectedTag pst in toReset)
            {
                if (ProfileSelectedTagFlags.None == (pst.Flags ^ flag))
                {
                    toRemove.Add(pst);
                }
                else
                {
                    pst.Flags = pst.Flags ^ flag;
                }
            }

            context.RemoveRange(toRemove);

            if ((toStay.Count() + currentWithoutFlagToSet.Count()) < ids.Count())
            {
                IEnumerable <int> alreadySetTags = new[]
                {
                    toStay,
                    currentWithoutFlagToSet.Select(pst => pst.TagID),
                }
                .SelectMany(t => t);
                IEnumerable <int> notSetTags = ids.Except(alreadySetTags);
                IEnumerable <ProfileSelectedTag> newSelections = notSetTags
                                                                 .Select(tagId => new ProfileSelectedTag
                {
                    ID              = 0,
                    Flags           = flag,
                    BindedProfileID = profileId,
                    TagID           = tagId
                });
                context.ProfilesTagSelection.AddRange(newSelections);
            }

            await context.SaveChangesAsync();
        }
        public async Task <MonitoringSession> GetNewSession(
            int profileId
            )
        {
            bool hasMonitorTagFilter = await _context.ProfilesTagSelection
                                       .AnyAsync(pts => pts.BindedProfileID == profileId &&
                                                 ProfileSelectedTagFlags.Monitor ==
                                                 (pts.Flags & ProfileSelectedTagFlags.Monitor));

            int monitoredNodesNum = hasMonitorTagFilter
                ? await _context.ProfilesTagSelection.AsNoTracking()
                                    .Where(pts => pts.BindedProfileID == profileId &&
                                           ProfileSelectedTagFlags.Monitor ==
                                           (pts.Flags & ProfileSelectedTagFlags.Monitor))
                                    .Include(pts => pts.Tag)
                                    .ThenInclude(t => t.Attachments)
                                    .ThenInclude(ta => ta.Node)
                                    .SelectMany(pts => pts.Tag.Attachments.Select(ta => ta.Node))
                                    .Where(n => n.OpenPing)
                                    .Select(n => n.ID)
                                    .Distinct()
                                    .CountAsync()
                : await _context.Nodes.CountAsync(n => n.OpenPing);

            MonitoringSession newSession = new MonitoringSession
            {
                ID = 0,
                CreatedByProfileID    = profileId,
                ParticipatingNodesNum = monitoredNodesNum,
                CreationTime          = JsDateTimeNow(),
                LastPulseTime         = 0,
            };

            _context.MonitoringSessions.Add(newSession);
            await _context.SaveChangesAsync();

            _context.Entry(newSession).State = EntityState.Detached;
            return(newSession);
        }