private static Type InternalGetPropertyType(Type type, string property)
        {
            property = SanitizePropertyName(type, property);

#if PROFILE
            using (Performance.Measure("InternalGetPropertyType"))
#endif
            {
                IBindableType bindableType = null;

                if (BindableMetadataProvider != null)
                {
                    var bindablePropertyDescriptor = BindablePropertyDescriptor.GetPropertByBindableMetadataProvider(type, property);

                    if (bindablePropertyDescriptor.OwnerType != null)
                    {
                        if (IsIndexerFormat(property))
                        {
                            if (bindableType.GetIndexerGetter() != null)
                            {
                                // In the case of bindable properties, the return
                                // type of an indexer is always an object.
                                return(typeof(object));
                            }
                        }

                        if (bindablePropertyDescriptor.Property != null)
                        {
                            // In the case of bindable properties, the return
                            // type of an indexer is always an object.
                            return(bindablePropertyDescriptor.Property.PropertyType);
                        }
                        else
                        {
                            _log.ErrorFormat("The [{0}] property does not exist on type [{1}]", property, type);
                            return(null);
                        }
                    }
                }

#if PROFILE
                using (Performance.Measure("InternalGetPropertyType.Reflection"))
#endif
                {
                    if (_log.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
                    {
                        _log.Debug($"GetPropertyType({type}, {property}) [Reflection]");
                    }

                    // Fallback on reflection-based lookup
                    if (IsIndexerFormat(property))
                    {
                        // Fallback on reflection-based lookup
                        var indexerInfo = GetPropertyInfo(type, "Item", allowPrivateMembers: false);

                        if (indexerInfo != null)
                        {
                            return(indexerInfo.PropertyType);
                        }
                        else
                        {
                            _log.ErrorFormat("The Indexer property getter does not exist on type [{0}]", type);
                            return(null);
                        }
                    }

                    var propertyInfo = GetPropertyInfo(type, property, allowPrivateMembers: false);

                    if (propertyInfo != null)
                    {
                        return(propertyInfo.PropertyType);
                    }

                    // Look for an attached property
                    var attachedPropertyGetter = GetAttachedPropertyGetter(type, property);

                    if (attachedPropertyGetter != null)
                    {
                        return(attachedPropertyGetter.ReturnType);
                    }

                    _log.ErrorFormat("The [{0}] property getter does not exist on type [{1}]", property, type);
                    return(null);
                }
            }
        }
 private BindablePropertyDescriptor(IBindableType ownerType, IBindableProperty property)
 {
     OwnerType = ownerType;
     Property  = property;
 }