void SetupService(VisualElement scrollContainer, VisualTreeAsset serviceTemplate, SingleService singleService)
        {
            scrollContainer.Add(serviceTemplate.CloneTree().contentContainer);
            var serviceIconAsset = EditorGUIUtility.Load(singleService.pathTowardIcon) as Texture2D;
            var serviceRoot      = scrollContainer[scrollContainer.childCount - 1];

            serviceRoot.name = singleService.name;

            var serviceTitle = serviceRoot.Q <TextElement>(className: k_ServiceTitleClassName);

            serviceTitle.text = singleService.title;
            serviceRoot.Q <TextElement>(className: k_ServiceDescriptionClassName).text = singleService.description;
            serviceRoot.Q(className: k_ServiceIconClassName).style.backgroundImage     = serviceIconAsset;

            Action openServiceSettingsLambda = () =>
            {
                ServicesUtils.OpenServicesProjectSettings(singleService);
            };

            m_ClickableByServiceName.Add(singleService.name, new Clickable(openServiceSettingsLambda));

            SetupServiceStatusLabel(serviceRoot, singleService);
            SetupPackageInstall(serviceRoot, singleService);
        }
        void LoadWindow()
        {
            rootVisualElement.Clear();

            var mainTemplate = EditorGUIUtility.Load(k_ServicesWindowUxmlPath) as VisualTreeAsset;

            rootVisualElement.AddStyleSheetPath(ServicesUtils.StylesheetPath.servicesWindowCommon);
            rootVisualElement.AddStyleSheetPath(EditorGUIUtility.isProSkin ? ServicesUtils.StylesheetPath.servicesWindowDark : ServicesUtils.StylesheetPath.servicesWindowLight);

            mainTemplate.CloneTree(rootVisualElement, new Dictionary <string, VisualElement>(), null);
            notificationSubscriber = new UIElementsNotificationSubscriber(rootVisualElement);
            notificationSubscriber.Subscribe(
                Notification.Topic.AdsService,
                Notification.Topic.AnalyticsService,
                Notification.Topic.BuildService,
                Notification.Topic.CollabService,
                Notification.Topic.CoppaCompliance,
                Notification.Topic.CrashService,
                Notification.Topic.ProjectBind,
                Notification.Topic.PurchasingService
                );

            rootVisualElement.Q <Button>(k_ProjectSettingsBtnName).clicked += () =>
            {
                ServicesUtils.OpenServicesProjectSettings(GeneralProjectSettings.generalProjectSettingsPath, typeof(GeneralProjectSettings).Name);
            };

            var dashboardClickable = new Clickable(() =>
            {
                if (!ServicesConfiguration.instance.pathsReady)
                {
                    NotificationManager.instance.Publish(Notification.Topic.ProjectBind, Notification.Severity.Error, L10n.Tr(k_ConnectionFailedMessage));
                }
                else if (UnityConnect.instance.projectInfo.projectBound)
                {
                    EditorAnalytics.SendOpenDashboardForService(new ServicesProjectSettings.OpenDashboardForService()
                    {
                        serviceName    = k_WindowTitle,
                        url            = ServicesConfiguration.instance.baseDashboardUrl,
                        organizationId = UnityConnect.instance.projectInfo.organizationId,
                        projectId      = UnityConnect.instance.projectInfo.projectId
                    });
                    Application.OpenURL(ServicesConfiguration.instance.GetCurrentProjectDashboardUrl());
                }
                else
                {
                    NotificationManager.instance.Publish(Notification.Topic.ProjectBind, Notification.Severity.Warning, L10n.Tr(k_ProjectNotBoundMessage));
                    ServicesUtils.OpenServicesProjectSettings(GeneralProjectSettings.generalProjectSettingsPath, typeof(GeneralProjectSettings).Name);
                }
            });

            rootVisualElement.Q(k_DashboardLinkName).AddManipulator(dashboardClickable);

            m_SortedServices = new SortedList <string, SingleService>();
            bool needProjectListOfPackage = false;

            foreach (var service in ServicesRepository.GetServices())
            {
                m_SortedServices.Add(service.title, service);
                if (service.isPackage && service.packageId != null)
                {
                    needProjectListOfPackage = true;
                }
            }
            // Only launch the listing if a service really needs the packages list...
            m_PackageCollection = null;
            if (needProjectListOfPackage)
            {
                m_ListRequestOfPackage    = Client.List();
                EditorApplication.update += ListingCurrentPackageProgress;
            }
            else
            {
                FinalizeServiceSetup();
            }
        }