public static IUIAutomationElement FindDescendantByName(
            this IUIAutomationElement parent,
            string name
            )
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            var condition = Helper.Automation.CreatePropertyCondition(
                AutomationElementIdentifiers.NameProperty.Id,
                name
                );
            var child = Helper.Retry(
                () => parent.FindFirst(TreeScope.TreeScope_Descendants, condition),
                AutomationRetryDelay,
                retryCount: AutomationRetryCount
                );

            if (child == null)
            {
                throw new InvalidOperationException(
                          $"Could not find item with name '{name}' under '{parent.GetNameForExceptionMessage()}'."
                          );
            }

            return(child);
        }
        /// <summary>
        /// Cycles through the <see cref="ToggleState"/>s of the given <see cref="IUIAutomationElement"/>.
        /// </summary>
        /// Throws an <see cref="InvalidOperationException"/> if <paramref name="element"/> does not
        /// support the <see cref="IUIAutomationTogglePattern"/>.
        public static void Toggle(this IUIAutomationElement element)
        {
            var togglePattern = element.GetCurrentPattern <IUIAutomationTogglePattern>(UIA_PatternIds.UIA_TogglePatternId);

            if (togglePattern != null)
            {
                RetryIfNotAvailable(
                    pattern => pattern.Toggle(),
                    togglePattern);
            }
            else
            {
                throw new InvalidOperationException($"The element '{element.GetNameForExceptionMessage()}' does not support the TogglePattern.");
            }
        }
        /// <summary>
        /// Returns true if the given <see cref="IUIAutomationElement"/> is in the <see cref="ToggleState.ToggleState_On"/> state.
        /// Throws an <see cref="InvalidOperationException"/> if <paramref name="element"/> does not
        /// support the <see cref="IUIAutomationTogglePattern"/>.
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static bool IsToggledOn(this IUIAutomationElement element)
        {
            var togglePattern = element.GetCurrentPattern <IUIAutomationTogglePattern>(UIA_PatternIds.UIA_TogglePatternId);

            if (togglePattern != null)
            {
                return(RetryIfNotAvailable(
                           pattern => pattern.CurrentToggleState == ToggleState.ToggleState_On,
                           togglePattern));
            }
            else
            {
                throw new InvalidOperationException($"The element '{element.GetNameForExceptionMessage()}' does not support the TogglePattern.");
            }
        }
        /// <summary>
        /// Sets the value of the given <see cref="IUIAutomationElement"/>.
        /// Throws an <see cref="InvalidOperationException"/> if <paramref name="element"/> does not
        /// support the <see cref="IUIAutomationValuePattern"/>.
        /// </summary>
        public static void SetValue(this IUIAutomationElement element, string value)
        {
            var valuePattern = element.GetCurrentPattern <IUIAutomationValuePattern>(UIA_PatternIds.UIA_ValuePatternId);

            if (valuePattern != null)
            {
                RetryIfNotAvailable(
                    pattern => pattern.SetValue(value),
                    valuePattern);
            }
            else
            {
                throw new InvalidOperationException($"The element '{element.GetNameForExceptionMessage()}' does not support the ValuePattern.");
            }
        }
        /// <summary>
        /// Selects an <see cref="IUIAutomationElement"/>.
        /// Throws an <see cref="InvalidOperationException"/> if <paramref name="element"/> does not
        /// support the <see cref="IUIAutomationSelectionItemPattern"/>.
        /// </summary>
        public static void Select(this IUIAutomationElement element)
        {
            var selectionItemPattern = element.GetCurrentPattern <IUIAutomationSelectionItemPattern>(UIA_PatternIds.UIA_SelectionItemPatternId);

            if (selectionItemPattern != null)
            {
                RetryIfNotAvailable(
                    pattern => pattern.Select(),
                    selectionItemPattern);
            }
            else
            {
                throw new InvalidOperationException($"The element '{element.GetNameForExceptionMessage()}' does not support the SelectionItemPattern.");
            }
        }
        /// <summary>
        /// Expands an <see cref="IUIAutomationElement"/>.
        /// Throws an <see cref="InvalidOperationException"/> if <paramref name="element"/> does not
        /// support the <see cref="IUIAutomationExpandCollapsePattern"/>.
        /// </summary>
        public static void Expand(this IUIAutomationElement element)
        {
            var expandCollapsePattern = element.GetCurrentPattern <IUIAutomationExpandCollapsePattern>(UIA_PatternIds.UIA_ExpandCollapsePatternId);

            if (expandCollapsePattern != null)
            {
                RetryIfNotAvailable(
                    pattern => pattern.Expand(),
                    expandCollapsePattern);
            }
            else
            {
                throw new InvalidOperationException($"The element '{element.GetNameForExceptionMessage()}' does not support the ExpandCollapsePattern.");
            }
        }
        /// <summary>
        /// Given an <see cref="IUIAutomationElement"/>, returns a descendant with the className specified by <paramref name="className"/>.
        /// Throws an <see cref="InvalidOperationException"/> if no such descendant is found.
        /// </summary>
        public static IUIAutomationElement FindDescendantByClass(this IUIAutomationElement parent, string className)
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            var condition = Helper.Automation.CreatePropertyCondition(AutomationElementIdentifiers.ClassNameProperty.Id, className);
            var child     = parent.FindFirst(TreeScope.TreeScope_Descendants, condition);

            if (child == null)
            {
                throw new InvalidOperationException($"Could not find item with class '{className}' under '{parent.GetNameForExceptionMessage()}'.");
            }

            return(child);
        }