public static void Register()
        {
            ViewModelBinder.BindProperties = BindProperties;
            var defaultSetBinding = ConventionManager.SetBinding;

            //ConventionManager.ApplyItemTemplate - Будет пытаться установить
            //шаблон для NotifyValue<List<string>> Producers
            //тк будет думать что NotifyValue биндинг будет производиться
            //к Producers а на самом деле биндинг будет к Producers.Value
            //это сделает ConventionManager.Set
            ConventionManager.AddElementConvention <Selector>(Selector.ItemsSourceProperty,
                                                              "SelectedItem",
                                                              "SelectionChanged")
            .ApplyBinding = (viewModelType, path, property, element, convention) => {
                Patch(ref path, ref property);
                var ignore = ConventionManager.SetBindingWithoutBindingOrValueOverwrite(viewModelType,
                                                                                        path,
                                                                                        property,
                                                                                        element,
                                                                                        convention,
                                                                                        ItemsControl.ItemsSourceProperty);

                if (!ignore)
                {
                    return(false);
                }

                ConventionManager.ConfigureSelectedItem(element, Selector.SelectedItemProperty, viewModelType, path);
                if (IsArrayOfPrimitive(property.PropertyType))
                {
                    return(true);
                }

                if (!(element is PopupSelector))
                {
                    ConventionManager.ApplyItemTemplate((ItemsControl)element, property);
                }

                return(true);
            };

            ConventionManager.ConfigureSelectedItem =
                (selector, selectedItemProperty, viewModelType, path) => {
                if (ConventionManager.HasBinding(selector, selectedItemProperty))
                {
                    return;
                }

                var baseName = path;
                if (path.EndsWith(".Value"))
                {
                    var index = path.LastIndexOf('.');
                    baseName = path.Substring(0, index);
                }

                foreach (var potentialName in ConventionManager.DerivePotentialSelectionNames(baseName))
                {
                    var propertyInfo = viewModelType.GetPropertyCaseInsensitive(potentialName);
                    if (propertyInfo != null)
                    {
                        var selectionPath = potentialName;
                        if (IsNotifyValue(propertyInfo))
                        {
                            selectionPath += ".Value";
                        }

                        var binding = new Binding(selectionPath)
                        {
                            Mode = BindingMode.TwoWay
                        };
                        var shouldApplyBinding = ConventionManager.ConfigureSelectedItemBinding(selector,
                                                                                                selectedItemProperty,
                                                                                                viewModelType,
                                                                                                selectionPath,
                                                                                                binding);

                        if (shouldApplyBinding)
                        {
                            BindingOperations.SetBinding(selector, selectedItemProperty, binding);
                            return;
                        }
                    }
                }
            };

            ConventionManager.SetBinding =
                (viewModelType, path, property, element, convention, bindableProperty) => {
                Patch(ref path, ref property);
                defaultSetBinding(viewModelType, path, property, element, convention, bindableProperty);
            };

            var basePrepareContext = ActionMessage.PrepareContext;

            ActionMessage.PrepareContext = context => {
                ActionMessage.SetMethodBinding(context);
                if (context.Target == null || context.Method == null)
                {
                    return;
                }

                var guardName  = "Can" + context.Method.Name;
                var targetType = context.Target.GetType();

                var guard = targetType.GetProperty(guardName);
                if (guard == null || !IsNotifyValue(guard))
                {
                    basePrepareContext(context);
                    return;
                }

                var inpc = guard.GetValue(context.Target, null) as INotifyPropertyChanged;
                if (inpc == null)
                {
                    return;
                }

                PropertyChangedEventHandler handler = null;
                handler = (s, e) => {
                    if (context.Message == null)
                    {
                        inpc.PropertyChanged -= handler;
                        return;
                    }
                    context.Message.UpdateAvailability();
                };

                inpc.PropertyChanged      += handler;
                context.Disposing         += delegate { inpc.PropertyChanged -= handler; };
                context.Message.Detaching += delegate { inpc.PropertyChanged -= handler; };

                context.CanExecute = () => (NotifyValue <bool>)guard.GetValue(context.Target, null);
            };
        }