/// <summary>
        /// CurrentIndexProperty property changed handler.
        /// </summary>
        /// <param name="d">DomainUpDown instance that changed its CurrentIndex.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnCurrentIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DomainUpDown source   = (DomainUpDown)d;
            int          newValue = (int)e.NewValue;
            int          oldValue = (int)e.OldValue;

            // validate newValue
            if (!source.IsValidCurrentIndex(newValue))
            {
                // revert back to e.OldValue
                source._currentIndexNestLevel++;
                source.SetValue(e.Property, e.OldValue);
                source._currentIndexNestLevel--;

                if (source._currentIndexDuringInitialization == null)
                {
                    // index is set but no items have been added yet
                    // cache the value
                    source._currentIndexDuringInitialization = newValue;
                    return;
                }
                else
                {
                    // throw exception
                    string message = string.Format(
                        CultureInfo.InvariantCulture,
                        Properties.Resources.DomainUpDown_CurrentIndex_InvalidValue,
                        e.NewValue);
                    throw new ArgumentOutOfRangeException("e", message);
                }
            }

            if (source._currentIndexNestLevel == 0)
            {
                // remember initial state
                source._initialCurrentIndex = oldValue;
            }

            source._currentIndexNestLevel++;

            // coerce newValue
            int coercedValue = source.CoerceSelectedIndex(newValue);

            if (newValue != coercedValue)
            {
                // always set SelectedIndexProperty to coerced value
                source.CurrentIndex = coercedValue;
            }

            source._currentIndexNestLevel--;

            if (source._currentIndexNestLevel == 0 && source.CurrentIndex != source._initialCurrentIndex)
            {
                // fire changed event only at root level and when there is indeed a change
                source.OnCurrentIndexChanged(oldValue, source.CurrentIndex);
            }
        }
        /// <summary>
        /// ItemsSourceProperty property changed handler.
        /// </summary>
        /// <param name="d">DomainUpDown that changed its ItemsSource.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DomainUpDown dud = (DomainUpDown)d;

            dud.OnItemsSourceChanged(e.OldValue as IEnumerable, e.NewValue as IEnumerable);
        }
        /// <summary>
        /// IsCyclicProperty property changed handler.
        /// </summary>
        /// <param name="d">DomainUpDown instance that changed its IsCyclic value.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnIsCyclicPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DomainUpDown source = (DomainUpDown)d;

            source.SetValidSpinDirection();
        }