private void CheckNeedToResetArrangementId()
        {
            var phraseLevels = PhraseLevelRepository.TryGetLevels(Parent.XMLFileFullPath);

            if (phraseLevels is not null)
            {
                foreach (var phrase in DDCArrangement.Phrases)
                {
                    if (phraseLevels.ContainsKey(phrase.Name) &&
                        phraseLevels[phrase.Name] > phrase.MaxDifficulty)
                    {
                        const string msg = "At least one phrase has lower max difficulty compared to previous DD generation.";

                        Log(msg);
                        Parent.StatusMessages.Add(new ImproverMessage(msg + " The arrangement id should be reset.", MessageType.Warning));
                        return;
                    }
                }
            }
        }
        internal void Process()
        {
            Log("-------------------- Postprocessing Started --------------------");

            CheckPhraseIterationCount();

            var context = new ProcessorContext(DDCArrangement, Log);

            context
            // Remove temporary beats
            .ApplyFixIf(Parent.AddedBeats.Count > 0, new TemporaryBeatRemover(Parent.AddedBeats))

            // Restore anchors at the beginning of Noguitar sections
            .ApplyFixIf(Preferences.RestoreNoguitarSectionAnchors && Parent.NGAnchors.Count > 0, new NoguitarAnchorRestorer(Parent.NGAnchors))

            // Restore END phrase to original position if needed
            .ApplyFixIf(WasNonDDFile, new ENDPhraseProcessor(OldLastPhraseTime))

            // Removes DDC's noguitar phrase if it is no longer needed due to END phrase restoration
            .ApplyFixIf(WasNonDDFile, new UnnecessaryNGPhraseRemover())

            // Process chord names
            .ApplyFixIf(Preferences.FixChordNames && DDCArrangement.ChordTemplates.Count > 0, new ChordNameProcessor(Parent.StatusMessages))

            // Remove beats that come after the audio has ended
            .ApplyFixIf(Preferences.RemoveBeatsPastAudioEnd, new ExtraneousBeatsRemover())

            // Remove time signature events
            .ApplyFixIf(Preferences.RemoveTimeSignatureEvents, new TimeSignatureEventRemover())

            // Add second level to phrases with only one level
            .ApplyFixIf(Preferences.FixOneLevelPhrases, new OneLevelPhraseFixer())

            // Process custom events
            .ApplyFix(new CustomEventPostProcessor(Parent.StatusMessages))

            // Remove notes that are placeholders for anchors
            .ApplyFixIf(Preferences.RemoveAnchorPlaceholderNotes, new AnchorPlaceholderNoteRemover())

            // Removes "high density" statuses and chord notes from chords that have them
            .ApplyFixIf(Preferences.RemoveHighDensityStatuses, new HighDensityRemover());

            // Restore first noguitar section
            if (WasNonDDFile && FirstNGSectionTime.HasValue)
            {
                context.ApplyFix(new FirstNoguitarSectionRestorer(FirstNGSectionTime.Value));
            }

            if (WasNonDDFile)
            {
                RemoveTemporaryMeasures();

                if (Preferences.CheckForArrIdReset)
                {
                    CheckNeedToResetArrangementId();

                    PhraseLevelRepository.QueueForSave(Parent.XMLFileFullPath, DDCArrangement.Phrases);
                }
            }

            if (Preferences.RemoveTranscriptionTrack)
            {
                DDCArrangement.TranscriptionTrack = new Level();
            }

            ValidateDDCXML();

            Log("-------------------- Postprocessing Completed --------------------");
        }