public async Task <bool> IsDirty()
        {
            bool res = false;

            if (CheckedItems != null && SavedItems != null)
            {
                int checkedItems = CheckedItems.Where(i => i.IsChecked == true).Count();
                int savedItems   = SavedItems.Count(i => i.IsChecked == true);
                if (checkedItems > savedItems)
                {
                    res = true;
                }
                else
                {
                    foreach (ProcessAction pa in CheckedItems.Where(i => i.IsChecked == true))
                    {
                        if (pa.ProcessActionId == 0)
                        {
                            //it's action user checked voluntarily
                            //on the whole, items without id definitely haven't been saved yet
                            res = true;
                            break;
                        }
                        else if (SavedItems.Any(i => i.ProcessActionId == pa.ProcessActionId && i.IsChecked == false))
                        {
                            //there's at least 1 item that IsChecked=true in CheckedItems that wasn't checked in saved items

                            res = true;
                            break;
                        }
                    }
                }
            }

            return(res);
        }
        public async Task <string> Save(int handlingId, int processId, int?abandonReason = null)
        {
            try
            {
                Logger.Info("ActionListViewModel is starting. HandlingId={handlingId}, ProcessId={processId}, AbandonReason={abandonReason}", handlingId, processId, abandonReason);

                List <Task <string> > listOfTask = new List <Task <string> >();
                foreach (ProcessAction pa in CheckedItems.Where(i => i.IsMutable == true))
                {
                    Logger.Info("ProcessAction: ID={ProcessActionId}, IsChecked={IsChecked}, IsMutable={IsMutable}", pa.ProcessActionId, pa.IsChecked, pa.IsMutable);
                    pa.HandlingId = handlingId;
                    pa.ProcessId  = processId;
                    if (pa.IsChecked == false || pa.IsChecked == null)
                    {
                        pa.AbandonReasonId = abandonReason;
                    }

                    if (pa.IsMutable == true && (pa.IsChecked == true || (pa.IsChecked == false && abandonReason != null)))
                    {
                        //save changes to process action only when it's mutable and:
                        //- it's checked
                        //- it's not checked and the user provided a reason why he abandoned it

                        if (pa.ProcessActionId == 0)
                        {
                            listOfTask.Add(pa.Add());
                        }
                        else
                        {
                            listOfTask.Add(pa.Edit());
                        }
                    }
                }

                IEnumerable <string> results = await Task.WhenAll <string>(listOfTask);

                Task.Run(() => TakeSnapshot());
                if (results.Where(r => r != "OK").Any())
                {
                    return(string.Join("; ", results.Where(r => r != "OK")));
                }
                else
                {
                    return("OK");
                }
            }
            catch (InvalidCastException ex)
            {
                Logger.Error(ex);
                string additionalInfo = $"handlingId={handlingId}, processId={processId}, abandonReason={abandonReason}";
                Static.Functions.CreateError(ex, "InvalidCast", nameof(this.Save), this.GetType().Name, additionalInfo);
                return(ex.Message);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                string additionalInfo = $"handlingId={handlingId}, processId={processId}, abandonReason={abandonReason}";
                Static.Functions.CreateError(ex, "No connection", nameof(this.Save), this.GetType().Name, additionalInfo);
                return(ex.Message);
            }
        }