private void loadHitObjects(Mods Mods)
        {
            HitObjects = null; // In case we don't succeed at least we won't have any HitObjects anymore. Better than wrong behaviour if stuff is done on the old HitObjects

            if (HitObjectManager != null)
            {
                HitObjectManager.Dispose();
            }

            HitObjectManager = NewHitObjectManager();

            if (!Beatmap.HeadersLoaded)
            {
                // Don't trust the beatmap id written in the file! It might be wrong! (see the big black for instance)
                int BeatmapId = Beatmap.BeatmapId;
                Beatmap.ProcessHeaders();
                Beatmap.BeatmapId = BeatmapId;
            }

            HitObjectManager.SetBeatmap(Beatmap, Mods);

            loadTiming();

            HitObjectManager.UpdateVariables(false, false);

            if (!Beatmap.HeadersLoaded)
            {
                Debug.Print("Beatmap " + Beatmap.BeatmapId + " is corrupted.");
            }
            else
            {
                HitObjectManager.parse(FileSection.HitObjects, false);

                HitObjects = new List <HitObject>(HitObjectManager.hitObjects);

                // This needs to be executed here, because later on the static objects will potentially contain wrong information (e.g. AudioEngine's timing)
                PreprocessHitObjects();
            }
        }
        /// <summary>
        /// Process and load a single osz2 package.
        /// </summary>
        private static bool ProcessPackage(string filename, BeatmapTreeLevel treeLevel)
        {
            MapPackage package = Osz2Factory.TryOpen(filename);

            if (package == null)
            {
                NotificationManager.ShowMessage("Error reading " + Path.GetFileName(filename), Color.Red, 4000);
                return(false);
            }

            int mapsLoaded = 0;

            foreach (string file in package.MapFiles)
            {
                Beatmap b = new Beatmap {
                    Filename = file
                };

                if (InitialLoadComplete)
                {
                    int index = Beatmaps.BinarySearch(b);

                    if (index >= 0)
                    {
                        Beatmap found = Beatmaps[index];

                        if (found.InOszContainer)
                        {
                            found.DatabaseNotFound         = false;
                            found.BeatmapPresent           = true;
                            found.ContainingFolderAbsolute = filename;
                            found.InOszContainer           = true;

                            treeLevel.Beatmaps.Add(found);
                            mapsLoaded++;
                            continue;
                        }
                    }
                }

                b.BeatmapSetId = Convert.ToInt32(package.GetMetadata(MapMetaType.BeatmapSetID));
                b.BeatmapId    = package.GetIDByMap(file);

                b.ContainingFolderAbsolute = filename;
                b.InOszContainer           = true;
                b.AudioPresent             = true;
                b.BeatmapPresent           = true;

                b.ProcessHeaders();
                if (!b.HeadersLoaded)
                {
                    //failed?
                    continue;
                }

                b.NewFile = true;
                NewFilesList.Add(b);

                if (!b.AudioPresent && !b.BeatmapPresent)
                {
                    continue;
                }

                Add(b);
                lastAddedMap = b;
                treeLevel.Beatmaps.Add(b);
                mapsLoaded++;
            }

            Osz2Factory.CloseMapPackage(package);
            //package.Unlock();

            return(mapsLoaded > 0);
        }
        internal static void ProcessTree(BeatmapTreeLevel currentLevel)
        {
            if (currentLevel == null)
            {
                return;
            }

            //never process songs if we aren't the lead spectator.
            if (GameBase.Tournament && !GameBase.TournamentManager)
            {
                return;
            }

            //the number of stray .osu files found in this tree level.
            int strayBeatmapCount = 0;

            string folder = currentLevel.FullPath;

            if (currentLevel != Root)
            {
                InvokeOnStatusUpdate(folder.Replace(BeatmapManager.SongsDirectory, string.Empty).Trim('\\', '/'));
            }

#if !DEBUG
            try
            {
#endif

            bool isTopFolder = folder == BeatmapManager.SongsDirectory;

            if (!isTopFolder && InitialLoadComplete && (Current == null || Current.ContainingFolder == null || Current.ContainingFolderAbsolute != folder))
            {
                string relativeFolder = folder.Replace(SongsDirectory, string.Empty);
                bool   found          = false;

                //avoid hitting the filesystem at all wherever possible
                foreach (Beatmap fb in Beatmaps)
                {
                    if (fb.ContainingFolder != relativeFolder)
                    {
                        continue;
                    }

                    strayBeatmapCount++;
                    if (!fb.InOszContainer)
                    {
                        fb.DatabaseNotFound = false;

                        //we are matching based on filename here.
                        //the folder could have changed, and we need to update this change.
                        fb.ContainingFolderAbsolute = folder;

                        currentLevel.Beatmaps.Add(fb);

                        found = true;
                    }
                }

                if (found)
                {
                    TotalUniqueSets++;
                    return;
                }
            }

            //load osz2 packages
            foreach (string f in Directory.GetFiles(folder, "*.osz2"))
            {
                if (f == "LastUpload.osz2")
                {
                    break;
                }

                if (ProcessPackage(f, currentLevel))
                {
                    TotalUniqueSets++;
                }
            }

            //load osz directories
            foreach (string file in Directory.GetFiles(folder, "*.osu"))
            {
                strayBeatmapCount++;

                Beatmap b = new Beatmap {
                    Filename = Path.GetFileName(file)
                };

                if (InitialLoadComplete)
                {
                    int index = Beatmaps.BinarySearch(b);

                    if (index >= 0)
                    {
                        Beatmap found = Beatmaps[index];

                        //this condition is required to make sure we don't match an osz2 to a folder.
                        //this causes really weird results. this whole process could be improved to avoid this ugliness.
                        if (!found.InOszContainer)
                        {
                            found.DatabaseNotFound = false;
                            found.BeatmapPresent   = true;

                            //we are matching based on filename here.
                            //the folder could have changed, and we need to update this change.
                            found.ContainingFolderAbsolute = folder;

                            currentLevel.Beatmaps.Add(found);

                            continue;
                        }
                    }
                }

                b.ContainingFolderAbsolute = folder;
                try
                {
                    b.ProcessHeaders();
                }
                catch (UnauthorizedAccessException)
                {
                    Logger.Log($@"{b} could not be loaded. Insufficient permissions");
                    continue;
                }

                if (!b.AudioPresent && !b.BeatmapPresent)
                {
                    continue;
                }

                NewFilesList.Add(b);
                b.NewFile = true;

                Add(b);
                lastAddedMap = b;
                currentLevel.Beatmaps.Add(b);
            }

            if (strayBeatmapCount == 0 &&
                (currentLevel == Root ||
                 currentLevel.Parent == Root))
            {
                string   audioFilename = null;
                string[] files         = Directory.GetFiles(folder, @"*.mp3", SearchOption.TopDirectoryOnly);

                if (files.Length > 0)
                {
                    audioFilename = files[0];
                }

                if (audioFilename != null)
                {
                    Beatmap b = new Beatmap
                    {
                        AudioFilename            = Path.GetFileName(audioFilename),
                        Filename                 = Path.GetFileNameWithoutExtension(audioFilename) + @".osu",
                        DisplayTitle             = Path.GetFileName(audioFilename),
                        DisplayTitleNoArtist     = Path.GetFileName(audioFilename),
                        SortTitle                = Path.GetFileName(audioFilename),
                        AudioPresent             = true,
                        BeatmapPresent           = false,
                        ContainingFolderAbsolute = folder
                    };


                    int index = Add(b);

                    if (index >= 0)
                    {
                        Beatmaps[index].DatabaseNotFound = false;
                    }

                    currentLevel.Beatmaps.Add(b);

                    lastAddedMap = b;

                    TotalAudioOnly++;
                }
            }

            if (strayBeatmapCount > 0)
            {
                TotalUniqueSets++;
            }

            if (isTopFolder || strayBeatmapCount == 0)
            //Only process subfolders if they don't have any direct beatmaps contained in them.
            {
                foreach (string f in Directory.GetDirectories(folder))
                {
                    ProcessFolder(f);
                }
            }
#if !DEBUG
        }

        catch (Exception e)
        {
            TopMostMessageBox.Show("Error while processing " + folder + "\n" + e.ToString());
        }
#endif
        }