List<string> VerifySongData(string midiTrackName, Sequence midiSequence, SongCacheItem songCacheItem)
        {
            var fileErrors = new List<string>();
            try
            {
                if (midiSequence.FirstOrDefault() == null)
                {
                    fileErrors.Add("No Tracks");
                }
                else
                {
                    var proTracks = midiSequence.Skip(1).ToList();
                    foreach (var track in proTracks)
                    {
                        if (track.Name != null && track.Name == "(no name)")
                        {
                            fileErrors.Add("******** Missing Track Name: " + (track.Name ?? ""));
                        }
                        else if (track.Name.IsProTrackName() == false)
                        {
                            fileErrors.Add("Invalid Track Name: " + (track.Name ?? ""));
                        }
                    }
                }
                foreach (var track in midiSequence)
                {
                    if (track.Name.IsEmpty())
                    {
                        fileErrors.Add("Null track name");
                    }
                    else if (track.Name.IsProTrackName() && midiSequence.IndexOf(track) == 0)
                    {
                        fileErrors.Add("Tempo must be first track");
                    }
                }

                var tracks = midiSequence.GetGuitarBassTracks().ToList();
                bool foundGuitarTrack = tracks.Any(x => x.Name.IsGuitarTrackName());
                bool foundBassTrack = tracks.Any(x => x.Name.IsBassTrackName());
                bool foundGuitar22 = tracks.Any(x => x.Name.IsGuitarTrackName22());
                bool foundBass22 = tracks.Any(x => x.Name.IsBassTrackName22());
                bool foundGuitar17 = tracks.Any(x => x.Name.IsGuitarTrackName17());
                bool foundBass17 = tracks.Any(x => x.Name.IsBassTrackName17());

                if (foundGuitarTrack == false)
                {
                    fileErrors.Add("No pro guitar track in midi file: " + midiTrackName);
                }
                if (foundBassTrack == false && (songCacheItem != null && songCacheItem.HasBass == true))
                {
                    fileErrors.Add("No pro bass track in midi file: " + midiTrackName);
                }

                if (foundGuitar22 == true && foundGuitar17 == false)
                {
                    fileErrors.Add("No 17 fret pro guitar track in file: " + midiTrackName);
                }
                if (foundBass22 == true && foundBass17 == false)
                {
                    fileErrors.Add("No 17 fret pro bass track in file: " + midiTrackName);
                }

                foreach (var currentTrack in tracks)
                {

                    var currentTrackName = currentTrack.Name ?? "(no name)";

                    if (!EditorPro.SetTrack6(midiSequence, currentTrack, GuitarDifficulty.Expert))
                    {
                        fileErrors.Add(currentTrackName + " Failed to set track ");
                        continue;
                    }

                    var metaNames = currentTrack.Meta.Where(x => x.MetaType == MetaType.TrackName).ToList();

                    if (!metaNames.Any())
                    {
                        fileErrors.Add("Contains Invalid track with no name");
                    }
                    else if (metaNames.Count() > 1)
                    {
                        fileErrors.Add(metaNames.First().Text + " Contains Extra track names:");
                        foreach (var en in metaNames)
                        {
                            fileErrors.Add(en.Text);
                        }
                    }

                    foreach (var diff in Utility.GetDifficultyIter())
                    {

                        EditorPro.CurrentDifficulty = diff;

                        var chords = EditorPro.Messages.Chords.ToList();
                        if (!chords.Any())
                        {
                            fileErrors.Add(currentTrackName + " No Chords Created !! " + diff);
                            continue;
                        }
                        if (diff.IsExpert())
                        {

                            if (EditorG5.IsLoaded)
                            {
                                var copyGuitarToBass = (songCacheItem != null && songCacheItem.CopyGuitarToBass == true);
                                if (currentTrackName.IsBassTrackName() && !copyGuitarToBass &&
                                    EditorG5.GetTrack(GuitarTrack.BassTrackName5) != null)
                                {
                                    EditorG5.SetTrack(GuitarTrack.BassTrackName5, diff);
                                }
                                else if (EditorG5.GetTrack(GuitarTrack.GuitarTrackName5) != null)
                                {
                                    EditorG5.SetTrack(GuitarTrack.GuitarTrackName5, diff);
                                }

                                if (EditorG5.Messages.BigRockEndings.Any() &&
                                    !EditorPro.Messages.BigRockEndings.Any())
                                {
                                    fileErrors.Add(currentTrackName + " Big Rock Ending in 5 button but not pro");
                                }

                                var solo5 = EditorG5.Messages.Solos.ToList();
                                var solo6 = EditorPro.Messages.Solos.ToList();

                                var missing5 = solo5.Where(x => !solo6.Any(sx => sx.TickPair == x.TickPair)).ToList();
                                if (missing5.Any())
                                {
                                    fileErrors.Add(currentTrackName + " Not all solos created ");
                                    fileErrors.AddRange(missing5.Select(m => m.TickPair.ToString()));
                                }

                                var power5 = EditorG5.Messages.Powerups.ToList();
                                var power6 = EditorPro.Messages.Powerups.ToList();

                                var missingpower5 = power5.Where(x => !power6.Any(sx => sx.TickPair == x.TickPair)).ToList();
                                if (missingpower5.Any())
                                {
                                    fileErrors.Add(currentTrackName + " Not all powerups snapped ");
                                    fileErrors.Add("Editor G5");
                                    fileErrors.AddRange(power5.Select(m => "    " + (missingpower5.Contains(m) ? " Missing->" : "") + m.TickPair.ToString()));
                                    fileErrors.Add("Editor G6");
                                    fileErrors.AddRange(power6.Select(m => "    " + m.TickPair.ToString()));
                                }

                            }

                            var handPositions = EditorPro.Messages.HandPositions.ToList();
                            if (!handPositions.Any())
                            {
                                fileErrors.Add(currentTrackName + " does not have hand position events (108) " + diff);
                            }
                            else
                            {
                                if (chords.First().DownTick < handPositions.First().DownTick)
                                {
                                    fileErrors.Add("108 hand position event occurs too late on track: " + (currentTrackName) + " " + diff);
                                }
                            }

                            if (chords.First().DownTick < 10)
                            {
                                fileErrors.Add("first chord is too soon in track: " + (currentTrackName) + " " + diff);
                            }

                            var tempotrack = EditorPro.GuitarTrack.GetTempoTrack();
                            if (tempotrack == null)
                            {
                                fileErrors.Add(currentTrackName + " no tempo track found");
                            }

                            if (!EditorPro.Messages.TimeSignatures.Any())
                            {
                                fileErrors.Add(currentTrackName + " Time signature missing from tempo track.");
                            }

                            if (!EditorPro.Messages.Tempos.Any())
                            {
                                fileErrors.Add(currentTrackName + " Tempo missing from tempo track.");
                            }
                        }

                        if (songCacheItem != null)
                        {
                            if (songCacheItem.CopyGuitarToBass == false)
                            {
                                if (currentTrackName.IsBassTrackName())
                                {

                                    var notesOver4 = chords.Where(c => c.Notes.Any(x=> x.NoteString > 3)).ToList();
                                    if (notesOver4.Any())
                                    {
                                        fileErrors.Add(currentTrackName + " " + notesOver4.Count + " Chords using more than 4 strings on bass: " + diff);
                                        fileErrors.AddRange(notesOver4.Select(m => m.ToString()));
                                    }
                                }
                            }
                        }

                        var noteAligns = chords.Where(x => x.Notes.NotesAligned == false).ToList();
                        if (noteAligns.Any())
                        {
                            fileErrors.Add(currentTrackName + " " + noteAligns.Count + " Note times not snapped: " + diff);
                            fileErrors.AddRange(noteAligns.Select(m => m.ToString()));
                        }

                        var modAligns = chords.Where(chord => chord.Modifiers.Any(modifier => modifier.TickPair != chord.TickPair)).ToList();
                        if (modAligns.Any())
                        {

                            fileErrors.Add(currentTrackName + " " + modAligns.Count + " Modifier times not snapped: " + diff);
                            fileErrors.AddRange(modAligns.Select(m => m.ToString() + " " + m.TickPair.ToString()));
                        }

                        var overlaps = chords.Take(chords.Count - 1).Where(x => x.UpTick > x.NextChord.DownTick).ToList();

                        if (overlaps.Any())
                        {
                            fileErrors.Add(currentTrackName + " " + overlaps.Count + " Overlapping notes found: " + diff);
                            fileErrors.AddRange(overlaps.Select(m => m.ToString()));
                        }

                        if (Utility.GetArpeggioData1(diff).IsNotNull())
                        {
                            var arpeggios = EditorPro.Messages.Arpeggios.ToList();
                            var arpeggioMissingChords = arpeggios.Where(x => chords.AnyBetweenTick(x.TickPair) == false).ToList();
                            if (arpeggioMissingChords.Any())
                            {
                                fileErrors.Add(currentTrackName + " " + arpeggioMissingChords.Count + " Arpeggios found with no chords: " + diff);
                                fileErrors.AddRange(arpeggioMissingChords.Select(m => m.ToString()));
                            }
                        }

                        if (diff.IsExpert())
                        {
                            var sstrem = EditorPro.Messages.SingleStringTremelos.ToList();
                            var modWithNoNotes = sstrem.Where(x => chords.AnyBetweenTick(x.TickPair) == false).ToList();

                            if (modWithNoNotes.Any())
                            {
                                fileErrors.Add(currentTrackName + " " + modWithNoNotes.Count + " Single string tremelo with no notes: " + diff);
                                fileErrors.AddRange(modWithNoNotes.Select(m => m.ToString()));
                            }
                        }

                        if (diff.IsExpert())
                        {
                            var trem = EditorPro.Messages.MultiStringTremelos.ToList();
                            var modWithNoNotes = trem.Where(x => chords.AnyBetweenTick(x.TickPair) == false).ToList();
                            if (modWithNoNotes.Any())
                            {
                                fileErrors.Add(currentTrackName + " " + modWithNoNotes.Count + " Multi string tremelo with no notes: " + diff);
                                fileErrors.AddRange(modWithNoNotes.Select(m => m.ToString()));
                            }
                        }

                        {
                            var powerups = EditorPro.Messages.Powerups.ToList();
                            var modWithNoNotes = powerups.Where(x => chords.AnyBetweenTick(x.TickPair) == false).ToList();

                            if (modWithNoNotes.Any())
                            {
                                fileErrors.Add(currentTrackName + " " + modWithNoNotes.Count + " Powerup with no notes: " + diff);
                                fileErrors.AddRange(modWithNoNotes.Select(m => m.ToString()));
                            }
                        }

                        var over17 = chords.Where(x => x.HighestFret > 17);
                        if (currentTrackName.IsProTrackName17() && over17.Any())
                        {
                            fileErrors.Add(currentTrackName + " Notes above 17 on Mustang chart: " + diff);
                            fileErrors.AddRange(over17.Select(m => m.ToString()));
                        }
                        var chordMix = chords.Where(x => x.Notes.Any(n => n.IsXNote) && x.Notes.Any(n => n.IsXNote) == false);
                        if (chordMix.Any())
                        {
                            fileErrors.Add(currentTrackName + " Mix of mute and non mute: " + diff);
                            fileErrors.AddRange(chordMix.Select(m => m.ToString()));
                        }

                        var numZero = chords.Count(x => x.HighestFret == 0);
                        var numNonZero = chords.Count(x => x.HighestFret != 0);

                        if (numNonZero == 0)
                        {
                            fileErrors.Add(currentTrackName + " No notes set: " + diff);
                        }

                        var shortChords = chords.Where(x => x.TickLength < 8);
                        if (shortChords.Any())
                        {
                            fileErrors.Add(currentTrackName + " invalid chord length found: " + diff);

                            shortChords.ForEach(x => fileErrors.Add("  " + x.ToString()));

                        }

                        var invStrum = chords.Where(x =>
                            (x.HasHighStrum && !x.HighStrumNotes.Any()) ||
                            (x.HasMidStrum && !x.MidStrumNotes.Any()) ||
                            (x.HasLowStrum && !x.LowStrumNotes.Any())
                            ).ToList();

                        if (invStrum.Any())
                        {
                            fileErrors.Add(currentTrackName + " " + diff + " strum marker missing notes");
                            fileErrors.AddRange(invStrum.Select(m => m.ToString()));
                        }

                    }
                }//end for each track

            }
            catch (Exception ex)
            {
                fileErrors.Add("Exception while checking file: " + ex.Message);
            }
            return fileErrors;
        }