/// <summary>
        /// Adds an additional owning type to the specified dependency property.
        /// </summary>
        /// <param name="dp">A <see cref="DependencyProperty"/> instance which identifies the dependency property to update.</param>
        /// <param name="ownerType">The type to add as an owner for the specified dependency property.</param>
        public static void AddOwner(DependencyProperty dp, Type ownerType)
        {
            Contract.Require(dp, "dp");
            Contract.Require(ownerType, "ownerType");

            RegisterInternal(dp, ownerType);
        }
        /// <summary>
        /// Registers a new attached property.
        /// </summary>
        /// <param name="name">The attached property's name.</param>
        /// <param name="uvssName">The attached property's name within the UVSS styling system.</param>
        /// <param name="propertyType">The attached property's value type.</param>
        /// <param name="ownerType">The attached property's owner type.</param>
        /// <param name="metadata">The attached property's metadata.</param>
        /// <returns>A <see cref="DependencyProperty"/> instance which represents the registered attached property.</returns>
        public static DependencyProperty RegisterAttached(String name, String uvssName, Type propertyType, Type ownerType, PropertyMetadata metadata = null)
        {
            Contract.Require(name, "name");
            Contract.Require(propertyType, "propertyType");
            Contract.Require(ownerType, "ownerType");

            var dp = new DependencyProperty(dpid++, name, uvssName, propertyType, ownerType, metadata, isAttached: true);
            RegisterInternal(dp, ownerType);
            return dp;
        }
        /// <summary>
        /// Unregisters the specified subscriber from receiving change notifications for the specified dependency property.
        /// </summary>
        /// <param name="dobj">The dependency object to monitor for changes.</param>
        /// <param name="dprop">The dependency property for which to stop receiving change notifications.</param>
        /// <param name="subscriber">The subscriber that wishes to stop receiving change notifications for the specified dependency property.</param>
        internal static void UnregisterChangeNotification(DependencyObject dobj, DependencyProperty dprop, IDependencyPropertyChangeNotificationSubscriber subscriber)
        {
            Contract.Require(dobj, "dobj");
            Contract.Require(dprop, "dprop");
            Contract.Require(subscriber, "subscriber");

            dprop.changeNotificationServer.Unsubscribe(dobj, subscriber);
        }
 /// <inheritdoc/>
 protected internal sealed override void ApplyStyle(UvssStyle style, UvssSelector selector, NavigationExpression? navigationExpression, DependencyProperty dp)
 {
     base.ApplyStyle(style, selector, navigationExpression, dp);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="DependencyPropertyKey"/> class.
        /// </summary>
        /// <param name="dependencyProperty">The <see cref="DependencyProperty"/> instance to which this key provides access.</param>
        internal DependencyPropertyKey(DependencyProperty dependencyProperty)
        {
            Contract.Require(dependencyProperty, nameof(dependencyProperty));

            this.dependencyProperty = dependencyProperty;
        }
        /// <summary>
        /// Registers the specified subscriber to receive change notifications for the specified dependency property.
        /// </summary>
        /// <param name="dobj">The dependency object to monitor for changes.</param>
        /// <param name="dprop">The dependency property for which to receive change notifications.</param>
        /// <param name="subscriber">The subscriber that wishes to receive change notifications for the specified dependency property.</param>
        internal static void RegisterChangeNotification(DependencyObject dobj, DependencyProperty dprop, IDependencyPropertyChangeNotificationSubscriber subscriber)
        {
            Contract.Require(dobj, nameof(dobj));
            Contract.Require(dprop, nameof(dprop));
            Contract.Require(subscriber, nameof(subscriber));

            dprop.changeNotificationServer.Subscribe(dobj, subscriber);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DependencyPropertyChangeNotificationServer"/> class.
        /// </summary>
        /// <param name="dprop">The dependency property that this notification server represents.</param>
        public DependencyPropertyChangeNotificationServer(DependencyProperty dprop)
        {
            Contract.Require(dprop, "dprop");

            this.dprop = dprop;
        }
        /// <summary>
        /// Registers the specified dependency property.
        /// </summary>
        /// <param name="dp">The dependency property to register.</param>
        /// <param name="ownerType">The owner type for which to register the dependency property.</param>
        private static void RegisterInternal(DependencyProperty dp, Type ownerType)
        {
            var propertyDomain = GetPropertyDomain(ownerType);
            if (propertyDomain.ContainsKey(dp.Name))
                throw new ArgumentException(PresentationStrings.DependencyPropertyAlreadyRegistered);

            propertyDomain[dp.Name] = dp;

            var stylingPropertyDomain = GetStylingPropertyDomain(ownerType);
            if (stylingPropertyDomain.ContainsKey(dp.UvssName))
                throw new ArgumentException(PresentationStrings.DependencyPropertyAlreadyRegistered);

            stylingPropertyDomain[dp.UvssName] = dp;
        }
        /// <summary>
        /// Registers a new read-only dependency property.
        /// </summary>
        /// <param name="name">The dependency property's name.</param>
        /// <param name="uvssName">The dependency property's name within the UVSS styling system.</param>
        /// <param name="propertyType">The dependency property's value type.</param>
        /// <param name="ownerType">The dependency property's owner type.</param>
        /// <param name="metadata">The dependency property's metadata.</param>
        /// <returns>A <see cref="DependencyPropertyKey"/> instance which provides access to the read-only dependency property.</returns>
        public static DependencyPropertyKey RegisterReadOnly(String name, String uvssName, Type propertyType, Type ownerType, PropertyMetadata metadata = null)
        {
            Contract.Require(name, nameof(name));
            Contract.Require(propertyType, nameof(propertyType));
            Contract.Require(ownerType, nameof(ownerType));

            var dp = new DependencyProperty(dpid++, name, uvssName, propertyType, ownerType, metadata, isReadOnly: true);
            RegisterInternal(dp, ownerType);
            return new DependencyPropertyKey(dp);
        }