public static void Generate(IEnumerable<ICrew> ecrews)
        {
            ILog logger = LogManager.GetCurrentClassLogger ();

            IList<ICrew> crews = ecrews.ToList();
            int showAthlete = Int32.Parse(ConfigurationManager.AppSettings ["showcompetitor"].ToString ());
            if(crews.Any(cr => cr.StartNumber > 0))
            {
                logger.Info ("crews have start numbers. ");
                if(crews.Any(cr => cr.StartNumber <= 0))
                    logger.Warn ("but some don't, that's not right - delete the start positions or fix the JSON.");
                Dump (crews, showAthlete);
                return;
            }
            IList<string> startpositions = new List<string> ();

            int lym = Int32.Parse (ConfigurationManager.AppSettings ["LastYearMen"].ToString ());
            int lyw = Int32.Parse(ConfigurationManager.AppSettings["LastYearWomen"].ToString());
            int lywo = Int32.Parse(ConfigurationManager.AppSettings["LastYearWomenOrder"].ToString());

            foreach(var crew in
                crews
                .Where(cr => !cr.IsScratched) //  && cr.IsAccepted)
                .OrderBy(cr => cr.EventCategory.Gender == Gender.Open && cr.PreviousYear.HasValue && cr.PreviousYear.Value <= lym ? cr.PreviousYear.Value : lym+1)
                    // if the cat order is before last year's women, observe it, otherwise part it - so that last year's women aren't directly behind last year's men.
                .ThenBy(cr => cr.Categories.First(cat => cat is EventCategory).Order < lywo ? cr.Categories.First(cat => cat is EventCategory).Order : lywo)

                .ThenBy(cr => cr.EventCategory.Gender == Gender.Female && cr.PreviousYear.HasValue && cr.PreviousYear.Value <= lyw ? cr.PreviousYear.Value : lyw+1)
                .ThenBy(cr => cr.Categories.First(cat => cat is EventCategory).Order)
                .ThenBy(cr => cr.CrewId.Reverse()))
            // todo - put the vets head vs scullers head into config
            //			foreach(var crew in
            //				crews
            //					.OrderBy(cr => cr.Categories.First(cat => cat is EventCategory).Order)
            //					.ThenBy(cr => cr.PreviousYear.HasValue && cr.PreviousYear.Value <= 3 ? cr.PreviousYear.Value : 5)
            //					.ThenBy(cr => cr.CrewId.Reverse()))
            {
                logger.InfoFormat("{0} [{2}], {1}, {3}, {4}",
                    crew.Name, crew.CategoryName,
                    crew.AthleteName(showAthlete, true), crew.CrewId,
                    crew.PreviousYear.HasValue ? crew.PreviousYear : -1);
                startpositions.Add(String.Format("{{\"CrewId\":{0},\"StartNumber\":{1}}}", crew.CrewId, startpositions.Count+1));
            }
            logger.Info(startpositions.Delimited());
        }