private void Authenticate(bool isFirstBoot, Action internalOnAuthenticated)
        {
            this.httpRequestHeaderDelegate    = OnHttpRequest;
            this.httpResponseHandlingDelegate = HttpResponseHandling;

            this.assetBundleListGetRequestHeaderDelegate        = OnAssetBundleListGetRequest;
            this.assetBundlePreloadListGetRequestHeaderDelegate = OnAssetBundlePreloadListGetRequest;
            this.assetBundleGetRequestHeaderDelegate            = OnAssetBundleGetRequest;

            Action onAuthSucceeded = () =>
            {
                internalOnAuthenticated();
                onAuthenticated();
            };
            Action <int, string> onBootAuthenticationRetryFailed = (code, reason) =>
            {
                onBootAuthFailed(code, reason);
            };
            Action <int, string> onRefreshAuthenticationRetryFailed = (code, reason) =>
            {
                onRefreshAuthFailed(code, reason);
            };

            _autoyaAuthRouter = new AuthRouter(
                this.mainthreadDispatcher,

                onAuthSucceeded,
                onBootAuthenticationRetryFailed,

                onAuthSucceeded,
                onRefreshAuthenticationRetryFailed,

                isFirstBoot
                );
        }
        /*
         *              Initializer
         */
        private IEnumerator InitializeAssetBundleFeature()
        {
            this.assetBundleListGetRequestHeaderDelegate        = OnAssetBundleListGetRequest;
            this.assetBundlePreloadListGetRequestHeaderDelegate = OnAssetBundlePreloadListGetRequest;
            this.assetBundleGetRequestHeaderDelegate            = OnAssetBundleGetRequest;

            // initialize AssetBundleListDownloader.
            AssetBundleListDownloader.HttpResponseHandlingDelegate httpResponseHandlingDel = (p1, p2, p3, p4, p5, p6, p7) =>
            {
                httpResponseHandlingDelegate(p1, p2, p3, p4, p5, p6, p7);
            };
            AssetBundleListDownloader.AssetBundleListGetRequestHeaderDelegate assetBundleGetRequestHeaderDel = (p1, p2) =>
            {
                return(assetBundleListGetRequestHeaderDelegate(p1, p2));
            };

            /*
             *  by default, only list downloader is ready on boot in AssetBundles feature.
             */
            _assetBundleListDownloader = new AssetBundleListDownloader(assetBundleGetRequestHeaderDel, httpResponseHandlingDel);

            // check if assetBundleList are stored.
            var storedLists          = LoadAssetBundleListsFromStorage();
            var storedListIdentities = storedLists.Select(list => list.identity).ToArray();

            // get assetBundleList identitiy from manifest info.
            var runtimeManifestContaindAssetBundleListIdentities = LoadAppUsingAssetBundleListIdentities();

            // remove unnecessary stored ABList if runtimeManifest is changed and ABListInfo is removed.
            {
                var storedMinusManifest = storedListIdentities.Except(runtimeManifestContaindAssetBundleListIdentities);

                if (storedMinusManifest.Any())
                {
                    OnRemoveUnnecessaryAssetBundleListsFromStorage(storedMinusManifest.ToArray());

                    // renew stored list identities.
                    storedLists          = LoadAssetBundleListsFromStorage();
                    storedListIdentities = storedLists.Select(list => list.identity).ToArray();
                }
            }

            // check stored ABList. if less than required by RuntimeManifest, need to download additional ABList.
            {
                var manifestMinusStored = runtimeManifestContaindAssetBundleListIdentities.Except(storedListIdentities);

                // not all assetBundleList are stored yet.
                // need to run AssetBundle_DownloadAssetBundleListsIfNeed().
                if (manifestMinusStored.Any())
                {
                    assetBundleFeatState = AssetBundlesFeatureState.None;
                    yield break;
                }
            }

            // all assetBundleList is stored and ready.
            foreach (var listCandidate in storedLists)
            {
                ReadyLoaderAndPreloader(listCandidate);
            }
            assetBundleFeatState = AssetBundlesFeatureState.Ready;
        }