/// <summary>
        ///     Downloads an AssetBundle or returns a cached AssetBundle if it has already been downloaded.
        ///     Remember to call <see cref="UnloadBundle(UnityEngine.AssetBundle,bool)" /> for every bundle you download once you
        ///     are done with it.
        /// </summary>
        /// <param name="bundleName">Name of the bundle to download.</param>
        /// <param name="onComplete">Action to perform when the bundle has been successfully downloaded.</param>
        /// <param name="downloadSettings">
        ///     Tell the function to use a previously downloaded version of the bundle if available.
        ///     Important!  If the bundle is currently "active" (it has not been unloaded) then the active bundle will be used
        ///     regardless of this setting.  If it's important that a new version is downloaded then be sure it isn't active.
        /// </param>
        public void GetBundle(string bundleName, Action <AssetBundle> onComplete, DownloadSettings downloadSettings)
        {
            if (Initialized == false)
            {
                Debug.LogError("AssetBundleManager must be initialized before you can get a bundle.");
                onComplete(null);
                return;
            }

            if (useHash)
            {
                try {
                    bundleName = unhashedToHashedBundleNameMap[bundleName];
                } catch {
                    Debug.LogWarningFormat("Unable to find hash for bundle [{0}], this request is likely to fail.", bundleName);
                }
            }

            AssetBundleContainer active;

            if (activeBundles.TryGetValue(bundleName, out active))
            {
                active.References++;
                onComplete(active.AssetBundle);
                return;
            }

            DownloadInProgressContainer inProgress;

            if (downloadsInProgress.TryGetValue(bundleName, out inProgress))
            {
                inProgress.References++;
                inProgress.OnComplete += onComplete;
                return;
            }

            downloadsInProgress.Add(bundleName, new DownloadInProgressContainer(onComplete));

            var mainBundle = new AssetBundleDownloadCommand {
                BundleName = bundleName,
                Hash       = downloadSettings == DownloadSettings.UseCacheIfAvailable ? Manifest.GetAssetBundleHash(bundleName) : default(Hash128),
                OnComplete = bundle => OnDownloadComplete(bundleName, bundle)
            };

            var dependencies           = Manifest.GetDirectDependencies(bundleName);
            var dependenciesToDownload = new List <string>();

            for (int i = 0; i < dependencies.Length; i++)
            {
                if (activeBundles.TryGetValue(dependencies[i], out active))
                {
                    active.References++;
                }
                else
                {
                    dependenciesToDownload.Add(dependencies[i]);
                }
            }

            if (dependenciesToDownload.Count > 0)
            {
                var dependencyCount = dependenciesToDownload.Count;
                Action <AssetBundle> onDependenciesComplete = dependency => {
                    if (--dependencyCount == 0)
                    {
                        handler.Handle(mainBundle);
                    }
                };

                for (int i = 0; i < dependenciesToDownload.Count; i++)
                {
                    var dependencyName = dependenciesToDownload[i];
                    GetBundle(dependencyName, onDependenciesComplete);
                }
            }
            else
            {
                handler.Handle(mainBundle);
            }
        }