private bool ProcessPath(IServiceProvider serviceProvider)
        {
            ////////////////////////////////////////////////////////////////////////////////
            //	Validation.
            ////////////////////////////////////////////////////////////////////////////////
            if (string.IsNullOrWhiteSpace(this.path))
            {
                binding = new Binding();
                return(true);
            }

            ////////////////////////////////////////////////////////////////////////////////
            //	Variables.
            ////////////////////////////////////////////////////////////////////////////////
            var parts     = this.path.Split('.').Select(o => o.Trim()).ToArray();
            var partIndex = 0;

            RelativeSource oRelativeSource = null;
            Object         oSource         = null;
            string         elementName     = null;

            ////////////////////////////////////////////////////////////////////////////////
            //	Determine and process the 'entry' binding type.
            ////////////////////////////////////////////////////////////////////////////////
            if (parts[0].StartsWith("#"))
            {
                elementName = parts[0].Substring(1);
                partIndex++;
            }
            else if (parts[0].ToLower() == "ancestors" || parts[0].ToLower() == "ancestor")
            {
                if (parts.Length < 2)
                {
                    throw new Exception("Invalid path, expected exactly 2 identifiers ancestors.#Type#.[Path] (e.g. Ancestors.DataGrid, Ancestors.DataGrid.SelectedItem, Ancestors.DataGrid.SelectedItem.Text)");
                }
                var sType = parts[1];
                var oType = (Type) new System.Windows.Markup.TypeExtension(sType).ProvideValue(serviceProvider);
                if (oType == null)
                {
                    throw new Exception("Could not find type: " + sType);
                }
                oRelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, oType, 1);
                partIndex      += 2;
            }
            else if (parts[0].ToLower() == "template" || parts[0].ToLower() == "templateparent" || parts[0].ToLower() == "templatedparent" || parts[0].ToLower() == "templated")
            {
                oRelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent);
                partIndex++;
            }
            else if (parts[0].ToLower() == "thiswindow" || parts[0].ToLower() == "window")
            {
                oRelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Window), 1);
                partIndex++;
            }
            else if (parts[0].ToLower() == "root")
            {
                IRootObjectProvider rootProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
                oSource = (rootProvider != null) ? rootProvider.RootObject : null;
                partIndex++;
            }
            else if (parts[0].ToLower() == "this")
            {
                oRelativeSource = new RelativeSource(RelativeSourceMode.Self);
                partIndex++;
            }

            ////////////////////////////////////////////////////////////////////////////////
            //	Advanced path.
            ////////////////////////////////////////////////////////////////////////////////
            var             partsForPathString  = parts.Skip(partIndex);
            IValueConverter callMethodConverter = null;

            ////////////////////////////////////////////////////////////////////////////////
            //	Special processing for binding to Methods and Commands.
            ////////////////////////////////////////////////////////////////////////////////
            if (partsForPathString.Any())
            {
                var sLastPartForPathString = partsForPathString.Last();

                if (sLastPartForPathString.EndsWith("()"))
                {
                    // Retrieve target info.
                    IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                    DependencyObject    targetObject       = null;
                    object targetProperty = null;
                    if (provideValueTarget != null)
                    {
                        targetObject   = provideValueTarget.TargetObject as DependencyObject;
                        targetProperty = provideValueTarget.TargetProperty;
                    }
                    if (targetProperty != null && targetProperty is DependencyProperty)
                    {
                        partsForPathString  = partsForPathString.Take(partsForPathString.Count() - 1);
                        methodName          = sLastPartForPathString.Remove(sLastPartForPathString.Length - 2);
                        callMethodConverter = new CallMethodValueConverter(methodName);
                    }
                    else if (targetProperty != null && targetProperty.GetType().FullName.Equals("System.Reflection.RuntimeEventInfo"))
                    //	else if (targetProperty != null  && targetProperty is System.Reflection.RuntimeEventInfo)
                    //	RuntimeEventInfo is locked away where I cant even compare against the type directly.
                    {
                        InternalBindToMethod(oSource, sLastPartForPathString, targetObject, targetProperty);

                        //  Return false indicating Parsing is done and we don't want to do any actual XAML binding.
                        //  We've already bound the proxy directly to the event object.
                        return(false);
                    }
                }
            }

            ////////////////////////////////////////////////////////////////////////////////
            //	Compute the 'Path'
            ////////////////////////////////////////////////////////////////////////////////
            var bindingPath = string.Join(".", partsForPathString.ToArray());

            ////////////////////////////////////////////////////////////////////////////////
            //	Build the Binding element.
            ////////////////////////////////////////////////////////////////////////////////
            if (string.IsNullOrWhiteSpace(bindingPath))
            {
                binding = new Binding();
            }
            else
            {
                binding = new Binding(bindingPath);
            }

            if (elementName != null)
            {
                binding.ElementName = elementName;
            }

            if (oRelativeSource != null)
            {
                binding.RelativeSource = oRelativeSource;
            }

            if (oSource != null)
            {
                binding.Source = oSource;
            }

            if (callMethodConverter != null)
            {
                binding.Converter = callMethodConverter;
            }
            else if (this.converter != null)
            {
                binding.Converter = this.converter;
            }


            ////////////////////////////////////////////////////////////////////////////////
            //	Build - Propagate Properties.
            //	- It turns out that property propagation validation is problematic.  We were trying to
            //	  determine if the user was trying to overwrite a property that previous processing has
            //	  already explicitly set.  In this situation we wanted to throw error/exception.
            //	- However, this is a problem in that several of Binding's properties are of value type and/or
            //	  get default values, so it is non trivial to determine if the above processing has set the value
            //	  or if it is just a default value; add to this that that default value can be different
            //	  based on which XAML property type is being bound to.
            //	- So to make this work completely, we'd have to depend solely on the processing the above
            //	  does; i.e. keep track of which binding properties the processing does.
            ////////////////////////////////////////////////////////////////////////////////
            ValidatePropagateProperty(binding.AsyncState, AsyncState);
            //	ValidatePropagateProperty(binding.BindsDirectlyToSource         ,	BindsDirectlyToSource);
            ValidatePropagateProperty(binding.ConverterCulture, ConverterCulture);
            ValidatePropagateProperty(binding.ConverterParameter, ConverterParameter);
            ValidatePropagateProperty(binding.ElementName, ElementName);
            //	ValidatePropagateProperty(binding.IsAsync                       ,	IsAsync);
            //	ValidatePropagateProperty(binding.Mode                          ,	Mode);
            //	ValidatePropagateProperty(binding.NotifyOnSourceUpdated         ,	NotifyOnSourceUpdated);
            //	ValidatePropagateProperty(binding.NotifyOnTargetUpdated         ,	NotifyOnTargetUpdated);
            //	ValidatePropagateProperty(binding.NotifyOnValidationError       ,	NotifyOnValidationError);
            //ValidatePropagateProperty(binding.RelativeSource              ,	RelativeSource);
            //ValidatePropagateProperty(binding.Source                      ,	Source);
            //ValidatePropagateProperty(binding.Path                        ,	Path);
            ValidatePropagateProperty(binding.UpdateSourceExceptionFilter, UpdateSourceExceptionFilter);
            //	ValidatePropagateProperty(binding.UpdateSourceTrigger           ,	UpdateSourceTrigger);
            //	ValidatePropagateProperty(binding.ValidatesOnDataErrors         ,	ValidatesOnDataErrors);
            //	ValidatePropagateProperty(binding.ValidatesOnExceptions         ,	ValidatesOnExceptions);
            //	ValidatePropagateProperty(binding.ValidatesOnNotifyDataErrors   ,	ValidatesOnNotifyDataErrors);
            //ValidatePropagateProperty(binding.ValidationRules { get); }	,	ValidationRules { get); }
            ValidatePropagateProperty(binding.XPath, XPath);

            if (AsyncState.HasValue())
            {
                binding.AsyncState = AsyncState;
            }
            if (BindsDirectlyToSource.HasValue)
            {
                binding.BindsDirectlyToSource = BindsDirectlyToSource.Value;
            }
            if (ConverterCulture.HasValue())
            {
                binding.ConverterCulture = ConverterCulture;
            }
            if (ConverterParameter.HasValue())
            {
                binding.ConverterParameter = ConverterParameter;
            }
            if (ElementName.HasValue())
            {
                binding.ElementName = ElementName;
            }
            if (IsAsync.HasValue)
            {
                binding.IsAsync = IsAsync.Value;
            }
            if (Mode.HasValue)
            {
                binding.Mode = Mode.Value;
            }
            if (NotifyOnSourceUpdated.HasValue)
            {
                binding.NotifyOnSourceUpdated = NotifyOnSourceUpdated.Value;
            }
            if (NotifyOnTargetUpdated.HasValue)
            {
                binding.NotifyOnTargetUpdated = NotifyOnTargetUpdated.Value;
            }
            if (NotifyOnValidationError.HasValue)
            {
                binding.NotifyOnValidationError = NotifyOnValidationError.Value;
            }
            //binding.RelativeSource                = RelativeSource;
            //binding.Source                        = Source;
            //binding.Path                          = Path;
            if (UpdateSourceExceptionFilter.HasValue())
            {
                binding.UpdateSourceExceptionFilter = UpdateSourceExceptionFilter;
            }
            if (UpdateSourceTrigger.HasValue)
            {
                binding.UpdateSourceTrigger = UpdateSourceTrigger.Value;
            }
            if (ValidatesOnDataErrors.HasValue)
            {
                binding.ValidatesOnDataErrors = ValidatesOnDataErrors.Value;
            }
            if (ValidatesOnExceptions.HasValue)
            {
                binding.ValidatesOnExceptions = ValidatesOnExceptions.Value;
            }
            if (ValidatesOnNotifyDataErrors.HasValue)
            {
                binding.ValidatesOnNotifyDataErrors = ValidatesOnNotifyDataErrors.Value;
            }
            if (Delay.HasValue)
            {
                binding.Delay = Delay.Value;
            }
            //binding.ValidationRules				= ValidationRules { get; }
            if (XPath.HasValue())
            {
                binding.XPath = XPath;
            }

            ////////////////////////////////////////////////////////////////////////////////
            //	Binding property set successfully.
            ////////////////////////////////////////////////////////////////////////////////
            return(true);
        }