public ActivitiesList Process(IEnumerable <string> nameFilter, bool includeNullTitles, DateTime from, DateTime until)
        {
            ActivitiesList activities = new ActivitiesList();

            RegistriesList registries = StraightDbHelper.GetRegistries(_connectionString);

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

            registries.Filter(nameFilter, includeNullTitles, from, until);
            if (registries.IsEmpty)
            {
                return(null);
            }

            while (!registries.IsEmpty)
            {
                Activity       activity = null;
                int            numOfRegistriesInActivity = DetectActivity(registries);
                RegistriesList activityRegistries        = ExtractActivity(registries, numOfRegistriesInActivity);
                activity = CreateActivity(activityRegistries);
                activities.Add(activity);
                activities.RegistriesIds.AddRange(activityRegistries.GetAllIds());
            }

            return(activities);
        }
        /// <summary>
        /// Counts the given in 'count' number of registries from the beginning (they form an activity),
        /// removes them from given registries list, returns this sublist (it contains end time of the activity)
        /// </summary>
        private static RegistriesList ExtractActivity(RegistriesList fromRegistries, int count)
        {
            var activity = fromRegistries.Take(count).ToList();

            fromRegistries.RemoveRange(0, count);
            var endTime = fromRegistries.IsEmpty ? fromRegistries.EndTime : fromRegistries[0].Time;

            return(new RegistriesList(activity, endTime));
        }
        /// <returns>
        /// Number of registries from the first (activityRegistries[0]) that form an activity
        /// </returns>
        private static int DetectActivity(RegistriesList registries)
        {
            int count            = 1;
            var activityWinTitle = registries[0].WindowTitle;

            while (count < registries.Count && registries[count].WindowTitle == activityWinTitle)
            {
                count++;
            }
            return(count);
        }
        /// <param name="quantity">Number of registries which processor obtains at a time from db and processes</param>
        /// <param name="includeNullTitles">Matters only if nameFilter != null</param>
        /// <param name="nameFilter">Filters out each registry which contains a given substring in its WindowTitle</param>
        /// <returns>
        /// NULL if there's no processible registries obtained or there's no more registries, so there's no more
        /// activities can be obtained.
        /// </returns>
        public List <Activity> Process(int quantity, bool includeNullTitles, IEnumerable <string> nameFilter)
        {
            List <Activity> activities = new List <Activity>();
            RegistriesList  registries;

            try
            {
                registries = GetRegistries(quantity);
            }
            catch (OnlyOneNonProcessedRegistryTakenException e)
            {
                MarkAsShouldNotBeProcessed(e.TheOnlyRemainingRegistry);
                return(null);
            }
            catch (NoNonProcessedRegistriesException)
            {
                return(null);
            }

            registries.Filter(nameFilter, includeNullTitles);

            if (registries.IsEmpty) // if all have been filtered out
            {
                MarkAsProcessed(registries.FilteredRegistries);
                return(null);
            }

            while (!registries.IsEmpty)
            {
                Activity       activity = null;
                int            numOfRegistriesInActivity = DetectActivity(registries);
                RegistriesList activityRegistries        = ExtractActivity(registries, numOfRegistriesInActivity);
                activity = CreateActivity(activityRegistries);
                activities.Add(activity);
                MarkAsProcessed(activityRegistries);
            }
            MarkAsProcessed(registries.FilteredRegistries);

            return(activities);
        }
        private static Activity CreateActivity(RegistriesList activityRegistries)
        {
            Activity activity = new Activity()
            {
                Name = activityRegistries.First.WindowTitle.NormalizeToMaxLength255() ?? "NULL"
            };

            activity.Measurements.Add(new Measurement()
            {
                Name  = "From",
                Type  = "DateTime",
                Value = activityRegistries.First.Time
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "Until",
                Type  = "DateTime",
                Value = activityRegistries.EndTime
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "Duration",
                Type  = "TimeSpan",
                Value = activityRegistries.Duration
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "Executable Path",
                Type  = "String",
                Value = activityRegistries.First.ExeModulePath.NormalizeToMaxLength255() ?? "NULL"
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "IP address",
                Type  = "String",
                Value = activityRegistries.First.IpAddress.Value.NormalizeToMaxLength255() ?? "NULL"
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "MAC address",
                Type  = "String",
                Value = activityRegistries.First.MacAddress.Value.NormalizeToMaxLength255() ?? "NULL"
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "User",
                Type  = "String",
                Value = activityRegistries.First.Username1.Value
            });
            if (activityRegistries.Any(r => r.Url != null))
            {
                activity.Measurements.Add(new Measurement()
                {
                    Name  = "URL",
                    Type  = "String",
                    Value = activityRegistries.FirstOrDefault(r => r.Url != null)?.Url.NormalizeToMaxLength255() ?? "NULL"
                });
            }

            return(activity);
        }
        protected static Activity CreateActivity(RegistriesList activityRegistries)
        {
            Activity activity = new Activity()
            {
                Name = activityRegistries.First.WindowTitle,
            };

            activity.Measurements.Add(new Measurement()
            {
                Name  = "From",
                Type  = "DateTime",
                Value = activityRegistries.First.Time
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "Until",
                Type  = "DateTime",
                Value = activityRegistries.EndTime
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "Duration",
                Type  = "TimeSpan",
                Value = activityRegistries.Duration
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "Executable Path",
                Type  = "String",
                Value = activityRegistries.First.ExeModulePath
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "IP address",
                Type  = "String",
                Value = activityRegistries.First.IpAddress.Value
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "MAC address",
                Type  = "String",
                Value = activityRegistries.First.MacAddress.Value
            });
            activity.Measurements.Add(new Measurement()
            {
                Name  = "User",
                Type  = "String",
                Value = activityRegistries.First.Username1.Value
            });
            if (activityRegistries.Any(r => r.Url != null))
            {
                activity.Measurements.Add(new Measurement()
                {
                    Name  = "URL",
                    Type  = "String",
                    Value = activityRegistries.First(r => r.Url != null).Url
                });
            }

            return(activity);
        }