public static GroupRacesDefinition[] RaceDefinitions(int cars, int rounds, LaneStat[] laneStats)
        {
            if (cars == 2) 
            {
                return new[]
                {
                    CreateGroupRaceDefinition(1, 1, 2, 3, 4),
                    CreateGroupRaceDefinition(2, 2, 1, 3, 4),
                };
            }
            if (cars == 3)
            {
                return new[]
                {
                    CreateGroupRaceDefinition(1, 1, 3, 2, 4),
                    CreateGroupRaceDefinition(2, 2, 1, 3, 4),
                    CreateGroupRaceDefinition(3, 3, 2, 1, 4),
                };
            }

            var raceDefPath = String.Format(@"C:\race-definitions\ppn-{0}x{1}x{2}.csv", cars, Lanes, rounds);
            var list = new List<GroupRacesDefinition>();
            if (File.Exists(raceDefPath))
            {
                var raceDefLines = File.ReadAllLines(raceDefPath);
                foreach (var raceDefLine in raceDefLines)
                {
                    var split = raceDefLine.Split('\t');
                    list.Add(CreateGroupRaceDefinition(int.Parse(split[0]), int.Parse(split[1]), int.Parse(split[2]),
                        int.Parse(split[3]), int.Parse(split[4])));
                }
                return list.ToArray();
            }
            var raceDefs = new PartialPerfectNGenerator().Build(cars, rounds);
            for (int i = 0; i < raceDefs.Length; i++)
            {
                list.Add(CreateGroupRaceDefinition(i+1, raceDefs[i][0], raceDefs[i][1], raceDefs[i][2], raceDefs[i][3]));
            }

            return list.ToArray();
        }
 private static int BuildTiebreakerRacesForPointLevel(Tournament tournament, string classKey, IEnumerable<CarResult> classGroup, int maxPoints, Group g,
     LaneStat[] laneStats, int byeCounter, string roundName, TournamentBuilder tiebreakerTournamentBuilder, int tiebreakerPlace)
 {
     var carsWithMaxPoints = classGroup.Where(r => r.Points == maxPoints).ToArray();
     var baseGroup = g.ShowClassStandings ? classKey : g.Name;
     if (carsWithMaxPoints.Count() > 1 && !tournament.Groups.Any(_g => _g.TiebreakGroup == baseGroup))
     {
         int i = 1;
         var tiedCars =
             carsWithMaxPoints.Select(
                 c =>
                     new Car
                     {
                         Builder = c.Car.Builder,
                         Class = c.Car.Class,
                         ID = c.Car.ID,
                         Name = c.Car.Name,
                         Number = i++
                     }).ToList();
         var raceDef = RaceDefinitionSource.RaceDefinitions(tiedCars.Count(), 1, laneStats);
         while (tiedCars.Count() < 4)
         {
             byeCounter++;
             var carId = "BYE" + byeCounter;
             tiedCars.Add(new Car {Builder = carId, Name = carId, ID = carId, Number = i});
             i++;
         }
         var name = tiebreakerPlace == 1
             ? string.Join("-", baseGroup.Split('-').First(), roundName)
             : string.Join("-", baseGroup.Split('-').First()+":"+tiebreakerPlace, roundName);
         var tiedGroup = new Group {Name = name, Cars = tiedCars.ToArray(), Round = roundName, TiebreakGroup = baseGroup};
         tiebreakerTournamentBuilder.AddGroup(tiedGroup, raceDef);
     }
     return byeCounter;
 }