/// <summary>
        /// Adds a class handler to the manager.
        /// </summary>
        /// <param name="classType">The type for which the handler is defined; must be a supertype of the manager's owner type.</param>
        /// <param name="handler">A delegate which represents the class handler to add to the type.</param>
        /// <param name="handledEventsToo">A value indicating whether the handler should receive events which have already been handled by other handlers.</param>
        public void AddHandler(Type classType, Delegate handler, Boolean handledEventsToo)
        {
            if (classType != this.ownerType && !this.ownerType.IsSubclassOf(classType))
                throw new ArgumentException(PresentationStrings.ClassTypeMustBeSubclassOfOwnerType.Format(classType.Name, ownerType.Name));

            if (routedEvent.DelegateType != handler.GetType())
                throw new ArgumentException(PresentationStrings.HandlerTypeMismatch.Format(handler.Method.Name, routedEvent.DelegateType.Name), "handler");

            lock (handlers)
            {
                var ordinalByType     = (short)0;
                var ordinalWithinType = ordinal++;

                var currentType = this.ownerType;
                while (currentType != classType)
                {
                    ordinalByType++;
                    currentType = currentType.BaseType;
                }

                var metadata = new RoutedEventHandlerMetadata(handler, ordinalByType, ordinalWithinType, handledEventsToo);
                handlers.Add(metadata);

                if (!sortSuspended)
                {
                    Sort();
                }
            }
        }
        /// <summary>
        /// Adds a handler to the specified routed event.
        /// </summary>
        /// <param name="evt">A <see cref="RoutedEvent"/> value which identifies the event to which to add a handler.</param>
        /// <param name="handler">A delegate which represents the handler to add to the specified routed event.</param>
        /// <param name="handledEventsToo">A value indicating whether the handler should receive events which have already been handled by other handlers.</param>
        public void Add(RoutedEvent evt, Delegate handler, Boolean handledEventsToo)
        {
            Contract.Require(evt, nameof(evt));
            Contract.Require(handler, nameof(handler));

            if (evt.DelegateType != handler.GetType())
                throw new ArgumentException(PresentationStrings.HandlerTypeMismatch.Format(handler.GetType().Name, evt.DelegateType.Name), "handler");

            lock (routedEventDelegates)
            {
                List<RoutedEventHandlerMetadata> events;
                if (!routedEventDelegates.TryGetValue(evt.ID, out events))
                {
                    events = new List<RoutedEventHandlerMetadata>();
                    routedEventDelegates[evt.ID] = events;
                }

                var routedEventInfo = new RoutedEventHandlerMetadata(handler, 0, 0, handledEventsToo);
                lock (events)
                {
                    events.Add(routedEventInfo);
                }
            }
        }
        /// <summary>
        /// Gets the next event handler to invoke for the current element.
        /// </summary>
        /// <param name="element">The element for which event handlers are being invoked.</param>
        /// <param name="evt">A <see cref="RoutedEvent"/> which identifies the routed event for which handlers are being invoked.</param>
        /// <param name="index">The index of the handler to invoke; this value is incremented by one when this method returns.</param>
        /// <param name="handler">The metadata for the handler that corresponds to the specified index within the handler list.</param>
        /// <returns><see langword="true"/> if a handler was retrieved for the specified index; otherwise, <see langword="false"/>.</returns>
        private static Boolean GetEventHandler(DependencyObject element, RoutedEvent evt, ref Int32 index, ref RoutedEventHandlerMetadata handler)
        {
            var indexTemp = index;

            var classHandlers = RoutedEventClassHandlers.GetClassHandlers(element.GetType(), evt);
            if (classHandlers != null)
            {
                lock (classHandlers)
                {
                    if (indexTemp >= 0 && indexTemp < classHandlers.Count)
                    {
                        handler = classHandlers[indexTemp];
                        index++;
                        return true;
                    }
                    indexTemp -= classHandlers.Count;
                }
            }

            var uiElement = element as UIElement;
            if (uiElement != null)
            {
                var instanceHandlers = uiElement.GetHandlers(evt);
                if (instanceHandlers == null)
                    return false;

                lock (instanceHandlers)
                {
                    if (indexTemp >= instanceHandlers.Count)
                    {
                        return false;
                    }
                    handler = instanceHandlers[indexTemp];
                    index++;
                }

                return true;
            }
            else
            {
                return false;
            }
        }