private ISelectableItem FindNextVisibleSelectableItem(bool reverseOrder)
        {
            // We use the `lastSelection` here as that is the one the user interacted last and it feels more natural that way when navigating with keyboard
            var lastSelection = m_PageManager.GetSelection().lastSelection;
            var packageItem   = GetPackageItem(lastSelection?.packageUniqueId);

            if (packageItem == null)
            {
                return(null);
            }

            // First we try to look for the next visible options within all the versions of the current package when the list is expanded
            if (packageItem.visualState.expanded)
            {
                m_PackageDatabase.GetPackageAndVersion(lastSelection, out var package, out var version);
                var selectedVersion = version ?? package?.versions.primary;

                var versionItem     = packageItem.versionItems.FirstOrDefault(v => v.targetVersion == selectedVersion);
                var nextVersionItem = UIUtils.FindNextSibling(versionItem, reverseOrder, UIUtils.IsElementVisible) as PackageVersionItem;
                if (nextVersionItem != null)
                {
                    return(nextVersionItem);
                }
            }

            var nextPackageItem = FindNextVisiblePackageItem(packageItem, reverseOrder);

            if (nextPackageItem == null)
            {
                return(null);
            }

            if (nextPackageItem.visualState.expanded)
            {
                var nextVersionItem = reverseOrder ? nextPackageItem.versionItems.LastOrDefault() : nextPackageItem.versionItems.FirstOrDefault();
                if (nextVersionItem != null)
                {
                    return(nextVersionItem);
                }
            }
            return(nextPackageItem);
        }
        private static PackageItem FindNextVisiblePackageItem(PackageItem packageItem, bool reverseOrder)
        {
            var nextVisibleItem = UIUtils.FindNextSibling(packageItem, reverseOrder, UIUtils.IsElementVisible) as PackageItem;

            if (nextVisibleItem == null)
            {
                Func <VisualElement, bool> nonEmptyGroup = (element) =>
                {
                    var group = element as PackageGroup;
                    return(group.packageItems.Any(p => UIUtils.IsElementVisible(p)));
                };
                var nextGroup = UIUtils.FindNextSibling(packageItem.packageGroup, reverseOrder, nonEmptyGroup) as PackageGroup;
                if (nextGroup != null)
                {
                    nextVisibleItem = reverseOrder ? nextGroup.packageItems.LastOrDefault(p => UIUtils.IsElementVisible(p))
                        : nextGroup.packageItems.FirstOrDefault(p => UIUtils.IsElementVisible(p));
                }
            }
            return(nextVisibleItem);
        }