private void SetupBinding(object source)
        {
            //sanity check
            if (source == null)
            {
                return;
            }

            var boundObject = BindExtension.GetObjectFromPath(source, this.Path.Path);

            if (boundObject == null)
            {
                return;
            }

            //set default BindingMode
            if (this.Mode == BindingMode.Default)
            {
                if (_bindingProperty.GetMetadata(_bindingTarget) is FrameworkPropertyMetadata metadata && metadata.BindsTwoWayByDefault)
                {
                    this.Mode = BindingMode.TwoWay;
                }
                else
                {
                    this.Mode = BindingMode.OneWay;
                }
            }
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget valueProvider)
            {
                _bindingTarget   = valueProvider.TargetObject as DependencyObject;
                _bindingProperty = valueProvider.TargetProperty as DependencyProperty;

                //DataContext, TODO other sources
                var dataContextSourceElement = BindExtension.FindDataContextSource(_bindingTarget);
                dataContextSourceElement.DataContextChanged += this.DataContextSource_DataContextChanged;

                this.SetupBinding(dataContextSourceElement.DataContext);
            }

            //return default
            return(_bindingProperty.DefaultMetadata.DefaultValue);
        }