private void UpdateParametersList()
        {
            using (TaskParameters.SuspendNotifications())
            {
                foreach (var dim in TaskParameters)
                {
                    dim.IsDuplicate = false;
                }

                var duplicatgroups = TaskParameters
                                     .GroupBy(dim => dim.Name)
                                     .Where(g => g.Count() > 1)
                                     .ToList();

                foreach (var group in duplicatgroups)
                {
                    foreach (var dim in group)
                    {
                        dim.IsDuplicate = true;
                    }
                }
            }
        }
        public void Initialize(ViewRequest viewRequest)
        {
            if (Shell.Role == ServiceUserRole.Editor)
            {
                Shell.AddVMCommand("File", "Save",
                                   "SaveChangesCommand", this)
                .SetHotKey(ModifierKeys.Control, Key.S);

                Shell.AddVMCommand("Edit", "Add operation from existing templates",
                                   "OpenTemplatesListCommand", this);

                Shell.AddVMCommand("Edit", "Add new operation",
                                   "CreateOperConfigCommand", this);
            }

            tasks.ClearAndAddRange(cachedService.Tasks.Items
                                   .Select(task => mapper.Map <DesktopTaskNameId>(task)));

            Schedules = cachedService.Schedules.SpawnCollection();

            if (viewRequest is TaskEditorRequest request)
            {
                mapper.Map(request.Task, this);
                HasSchedule = ScheduleId > 0;

                if (request.TaskOpers != null)
                {
                    bindedOpers.ClearAndAddRange(request.TaskOpers.OrderBy(to => to.Number)
                                                 .Select(to => mapper.Map <DesktopOperation>(to)));
                }

                if (request.Task.DependsOn != null)
                {
                    taskDependencies.ClearAndAddRange(request.Task.DependsOn
                                                      .Select(dep =>
                    {
                        tasks
                        .Connect()
                        .Bind(out var cachedTasks)
                        .Subscribe();

                        var desktopDep   = mapper.Map <DesktopTaskDependence>(dep);
                        desktopDep.Tasks = cachedTasks;

                        return(desktopDep);
                    }));
                }

                if (request.DependsOn != null)
                {
                    taskDependencies.ClearAndAddRange(request
                                                      .DependsOn.OrderBy(dep => dep.TaskId));
                }

                if (!string.IsNullOrEmpty(request.Task.Parameters))
                {
                    taskParameters.ClearAndAddRange(JsonConvert
                                                    .DeserializeObject <Dictionary <string, object> >(request.Task.Parameters)
                                                    .Select(pair => new TaskParameter
                    {
                        Name  = pair.Key,
                        Value = pair.Value
                    }));
                }

                TaskDependencies = new ObservableCollectionExtended <DesktopTaskDependence>();

                taskDependencies.Connect()
                .Bind(TaskDependencies)
                .Subscribe(_ => this.RaisePropertyChanged(nameof(TaskDependencies)));

                taskDependencies.Connect()
                .WhenAnyPropertyChanged("TaskId", "MaxSecondsPassed")
                .Subscribe(_ => this.RaisePropertyChanged(nameof(TaskDependencies)));

                if (request.ViewId == "Creating new Task")
                {
                    HasSchedule = true;
                    ScheduleId  = Schedules.First()?.Id;
                    Name        = "New task";
                }

                if (request.ViewId.Contains("copy"))
                {
                    Name = request.ViewId;
                }
            }

            void Changed(object sender, PropertyChangedEventArgs e)
            {
                if (Shell.Role == ServiceUserRole.Viewer || IsDirty || e.PropertyName == "SelectedOperation")
                {
                    return;
                }
                IsDirty = true;
                Title  += '*';
            }

            AllErrors.Connect()
            .Subscribe(_ => IsValid = !AllErrors.Items.Any());

            this.ObservableForProperty(s => s.HasSchedule)
            .Subscribe(hassch =>
                       ScheduleId = hassch.Value ? Schedules.FirstOrDefault()?.Id : null);

            taskParameters.Connect() //todo: real-time updating of duplicates indicators
            .WhenAnyPropertyChanged("Name")
            .Subscribe(_ =>
            {
                foreach (var dim in TaskParameters)
                {
                    dim.IsDuplicate = false;
                }

                var duplicatgroups = TaskParameters
                                     .GroupBy(dim => dim.Name)
                                     .Where(g => g.Count() > 1)
                                     .ToList();

                foreach (var group in duplicatgroups)
                {
                    foreach (var dim in group)
                    {
                        dim.IsDuplicate = true;
                        dim.HasErrors   = true;
                    }
                }

                this.RaisePropertyChanged(nameof(TaskParameters));
            });

            taskParameters.Connect()
            .WhenAnyPropertyChanged("Value")
            .Subscribe(_ => this.RaisePropertyChanged(nameof(TaskParameters)));

            taskParameters.Connect()
            .WhenAnyPropertyChanged("HasErrors")
            .Subscribe(_ =>
            {
                IsValid = !AllErrors.Items.Any() &&
                          !TaskParameters.Any(param => param.HasErrors);
            });

            TaskParameters = new ObservableCollectionExtended <TaskParameter>();

            taskParameters.Connect()
            .Bind(TaskParameters)
            .Skip(1)
            .Subscribe(_ =>
            {
                UpdateParametersList();
                this.RaisePropertyChanged(nameof(TaskParameters));
            });


            ImplementationTypes = implementationTypes.SpawnCollection();

            BindedOpers = new ObservableCollectionExtended <DesktopOperation>();

            bindedOpers.Connect()
            .Bind(BindedOpers)
            .Subscribe(_ => this.RaisePropertyChanged(nameof(bindedOpers)));



            bindedOpers.Connect()
            .Subscribe(_ =>
            {
                var packages = bindedOpers.Items.Where(oper => DataImporters.ContainsKey(oper.ImplementationType))
                               .Select(oper =>
                                       (DeserializeOperationConfigByType(oper.ImplementationType, oper.Config) as
                                        IPackagedImporterConfig)
                                       ?.PackageName).Where(name => !string.IsNullOrEmpty(name)).Distinct().ToList();

                incomingPackages.ClearAndAddRange(packages);
                this.RaisePropertyChanged(nameof(bindedOpers));
            });

            PropertyChanged += Changed;
        } //init vm