private static IEnumerator InternalDeInitialize(Action onDone)
        {
            var sw = Stopwatch.StartNew();

            // the initialize client
            OnUnloadClientSideContent?.Invoke();

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD", "Destroying players.");
            OnClientLoadingStart?.Invoke();

            LastMapState = QNetMapState.Unloading;
            OnMapStateChanged?.Invoke(LastMapState);

            // destroy players
            yield return(QNetPlayer.DestroyAllQNetPlayers());

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD",
                                               $"Destroying {QNetWorldSerializer.SerializedAndInstancedObjects.Count} objects.");

            // destroy world objects
            var isDestroyingWorldObjects = true;

            QNetWorldSerializer.DestroySerializedObjects(() => { isDestroyingWorldObjects = false; });
            while (isDestroyingWorldObjects)
            {
                yield return(new WaitForEndOfFrame());
            }

            // try to destroy rest of QNet objects just for sure
            if (QNetObjectBehaviour.SpawnedBehaviours.Length != 0)
            {
                JEMLogger.Log(
                    $"QNetUnity find and will destroy {QNetObjectBehaviour.SpawnedBehaviours.Length} additional objects that has been created not by QNetWorldSerializer.");
            }

            while (QNetObjectBehaviour.SpawnedBehaviours.Length > 0)
            {
                QNetObjectBehaviour.InternalDestroy(QNetObjectBehaviour.SpawnedBehaviours[0]);
                yield return(new WaitForEndOfFrame());
            }

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING LEVEL", "Unloading level.");

            // unload world
            var isLevelUnLoading = true;

            QNetLevelLoader.UnLoad(() => { isLevelUnLoading = false; });
            while (isLevelUnLoading)
            {
                yield return(new WaitForEndOfFrame());
            }

            // clear behaviours just for sure
            QNetObjectBehaviour.ClearBehaviours();

            LastMapState = QNetMapState.NotLoaded;
            OnMapStateChanged?.Invoke(LastMapState);

            GameIsDeInitializing = false;
            GameInitialized      = false;
            OnClientLoadingEnd?.Invoke();

            JEMLogger.Log($"QNetUnity DeInitialization main work took {sw.Elapsed.Milliseconds:0.00}ms.");
            onDone?.Invoke();
        }