// ===================================================

        /*
         #       #######  #####  ###  #####
         #       #     # #     #  #  #     #
         #       #     # #        #  #
         #       #     # #  ####  #  #
         #       #     # #     #  #  #
         #       #     # #     #  #  #     #
         ####### #######  #####  ###  #####  */

        // ===================================================

        private void loadAllAudioClipsIntoMemory(List <SoundMarker> markers, Layout layout, Action completion)
        {
            if (_managerDelegate == null || layout == null)
            {
                return;
            }
            Dictionary <string, SoundFile> sfDict = _managerDelegate.getSoundDictionary();
            int numLoaded = _managerDelegate.getNumLoadedInSoundDictionary();

            // UnityEngine.Debug.LogWarning("loadAllAudioClipsIntoMemory: " + numLoaded);
            LambdaWaiter <SoundFile> lambdaWaiter = new LambdaWaiter <SoundFile>();

            HashSet <SoundFile> loadingOrLoadedSoundFiles = new HashSet <SoundFile>();

            foreach (SoundMarker marker in markers)
            {
                SoundFile sf;
                if (!sfDict.TryGetValue(marker.hotspot.soundID, out sf))
                {
                    continue;
                }

                // The Marker SHOULD be loaded
                loadingOrLoadedSoundFiles.Add(sf);

                LoadClipInSoundFileOnCoroutine(sf, marker,
                                               lambdaWaiter.AddCallback((SoundFile returnedSoundFile) => {
                }));
            }

            foreach (SoundFile sf in sfDict.Values)
            {
                if (loadingOrLoadedSoundFiles.Contains(sf))
                {
                    continue;
                }
                loadingOrLoadedSoundFiles.Add(sf);

                // sf.loadState = LoadState.Loading;
                _managerDelegate?.StartCoroutineOn(SoundFile.LoadClipInSoundFile(sf,
                                                                                 lambdaWaiter.AddCallback((SoundFile returnedSoundFile) => {
                })));
            }

            lambdaWaiter.WaitForAllCallbacks(() => {
                _managerDelegate?.OnDemandLoadingLoadedAudioClipsChanged(this);
                if (completion != null)
                {
                    completion();
                }
            });
        }
        // --------------------------

        private void LoadClipInSoundFileOnCoroutine(SoundFile sf, SoundMarker marker, System.Action <SoundFile> completion = null)
        {
            if (sf.isDefaultSoundFile || (sf.loadState == LoadState.Success && sf.clip != null))
            {
                if (marker != null)
                {
                    marker.OnDemandSoundFileClipWasLoaded(sf);
                }
                completion(sf);
                return;
            }

            sf.loadState = LoadState.Loading;
            _managerDelegate?.StartCoroutineOn(SoundFile.LoadClipInSoundFile(sf,
                                                                             completion: (SoundFile returnedSoundFile) => {
                _managerDelegate?.OnDemandLoadingLoadedAudioClipsChanged(this);
                if (marker != null)
                {
                    marker.OnDemandSoundFileClipWasLoaded(returnedSoundFile);
                }
                completion(returnedSoundFile);
            }));
        }