//    private static string BNF = @"<expr> ::= <val> <op> <val> | <val> | 1 | 2
    //
    //<op> ::= + | - | *
    //
    //<val> ::= N_m | N_s";


    public void Start(Options options) {
      CFGParser pars = new CFGParser();

      var grammar = pars.readGrammarBNF(BNF);

      long possibilities = CalcPossibilitiesOfDepth(grammar, 2);
      System.Console.WriteLine(possibilities);
    }
    public void Start(Options options) {
      var reeval = new ReevaluateCFGPythonSolutionsInResultCollection();

      foreach (var filePath in options.InputFiles) {
        RunCollection coll = Helper.LoadRunCollection(filePath);
        if (Check(coll, filePath) == 2) {
          reeval.Reevaluate(coll, filePath, options.Timeout);
          Helper.printToConsole("Check again", Path.GetFileName(filePath));
          coll = Helper.LoadRunCollection(filePath);
          Check(coll, filePath);
        }
      }
    }
    public static void Main(string[] args) {
      try {
        var options = new Options();
        if (CommandLine.Parser.Default.ParseArguments(args, options)) {
          Console.WriteLine(String.Format("Used command: {0}", String.Join(" ", args.Select(x => x.Contains(" ") ? String.Format("\"{0}\"", x) : x))));

          options.InputFiles = ExpandWildcards(options.InputFiles);

          // initialize ContentManager once
          ContentManager.Initialize(new PersistenceContentManager());

          switch (options.Start) {
            case RunAs.split:
              (new SplitToSingleRuns()).Start(options);
              break;
            case RunAs.breakup:
              (new BreakupExperiment()).Start(options);
              break;
            case RunAs.collect:
              (new CollectRuns()).Start(options);
              break;
            case RunAs.reevaluate:
              (new ReevaluateCFGPythonSolutionsInResultCollection()).Start(options);
              break;
            case RunAs.update:
              (new HL13To14UpdateFileFixer()).Start(options);
              break;
            case RunAs.check:
              (new CheckResults()).Start(options);
              break;
            default:
              (new AllInOne()).Start(options);
              break;
          }

          //(new GrammarPossibilities()).Start(options);

          Console.WriteLine("All Threads finished successfully");
        }
      } catch (Exception e) {
        Console.WriteLine(e.Message);
        Console.WriteLine(e.StackTrace);
        while (e != null) {
          Console.WriteLine(e.Message);
          Console.WriteLine(e.StackTrace);
          e = e.InnerException;
        }

        Console.WriteLine("Exit with ERRORS!");
      }
    }
    public void Start(Options options) {
      foreach (var filePath in options.InputFiles) {
        var content = ContentManager.Load(filePath);

        var runs = content as RunCollection;
        if (runs != null) {
          if (runs.Any(r => r.Results.ContainsKey("Crossover Actual CutPoint Parent"))) {
            CrossoverCalc(runs, Path.GetFileNameWithoutExtension(filePath));
          }

          if (runs.Any(r => r.Results.ContainsKey("Manipulator Actual CutPoint Parent"))) {
            ManipulatorCalc(runs, Path.GetFileNameWithoutExtension(filePath));
          }
        } else {
          throw new ArgumentException("no Run collection");
        }
      }
    }
    public void Start(Options options) {
      foreach (var file in options.InputFiles) {
        string fileName = Path.GetFileName(file);
        using (var stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite)) {
          using (var zipFile = new ZipArchive(stream, ZipArchiveMode.Update)) {
            ZipArchiveEntry data = zipFile.Entries.Where(x => x.FullName.Equals("data.xml")).FirstOrDefault();
            ZipArchiveEntry typecache = zipFile.Entries.Where(x => x.FullName.Equals("typecache.xml")).FirstOrDefault();

            string tmp = null;
            XmlDocument doc = new XmlDocument();
            using (var s = new StreamReader(data.Open())) {
              tmp = s.ReadToEnd();
            }
            doc.LoadXml(tmp);
            var primitiveNode = doc.SelectNodes("//PRIMITIVE[contains(.,'GEArtificialAntEvaluator')]");
            if (primitiveNode.Count > 1 || primitiveNode.Count <= 0) {
              Helper.printToConsole("No GEArtificialAntEvaluator found", fileName);
              continue;
            }
            primitiveNode[0].ParentNode.ParentNode.RemoveChild(primitiveNode[0].ParentNode);

            string name = data.FullName;
            data.Delete();
            data = zipFile.CreateEntry(name);
            using (var s = new StreamWriter(data.Open())) {
              doc.Save(s);
            }

            using (var s = new StreamReader(typecache.Open())) {
              tmp = s.ReadToEnd();
            }
            tmp = string.Join(Environment.NewLine, tmp.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).Where(x => !x.Contains("GrammaticalEvolution")).ToArray());
            name = typecache.FullName;
            typecache.Delete();
            typecache = zipFile.CreateEntry(name);
            using (var s = new StreamWriter(typecache.Open())) {
              s.Write(tmp);
            }
          }
        }
      }
    }
    public void Start(Options options) {
      foreach (string filePath in options.InputFiles) {
        string fileName = Path.GetFileName(filePath);
        var experiment = LoadExperiment(filePath);
        if (experiment == null) {
          Helper.printToConsole("Error: This is not an experiment.", Path.GetFileName(filePath));
          continue;
        }

        experiment.Prepare();
        experiment.Runs.Clear();

        Dictionary<string, IOptimizer> store;
        if (experiment.Optimizers.Select(o => o.Name).Distinct().Count() == experiment.Optimizers.Count) {
          store = experiment.Optimizers.ToDictionary(o => o.Name);
        } else {
          Helper.printToConsole("Warning: Optimizer names are not unique.", Path.GetFileName(filePath));
          store = new Dictionary<string, IOptimizer>();
          foreach (var opt in experiment.Optimizers) {
            if (!store.ContainsKey(opt.Name)) {
              store.Add(opt.Name, opt);
            } else {
              int count = 1;
              while (store.ContainsKey(String.Format("{0} {1}", opt.Name, count))) {
                count++;
              }
              store.Add(opt.Name, opt);
            }
          }
        }

        foreach (var opt in store) {
          var storable = opt.Value as IStorableContent;
          if (storable == null) {
            Helper.printToConsole(String.Format("{0} is not a storeable content", opt.Key), Path.GetFileName(filePath));
            continue;
          }
          ContentManager.Save(storable, String.Format("{0}.hl", opt.Key), true);
        }
      }
    }
    public void Start(Options options) {
      int count = options.InputFiles.Count;
      if (count == 0) return;

      HeuristicLabWorkingThread[] hlWorkingThread = new HeuristicLabWorkingThread[count];
      Thread[] hlThreads = new Thread[count];
      WaitHandle[] finishedWaitHandles = new WaitHandle[count];

      for (int i = 0; i < count; i++) {
        ManualResetEventSlim finishedEvent = new ManualResetEventSlim(false, 1);
        finishedWaitHandles[i] = finishedEvent.WaitHandle;


        hlWorkingThread[i] = new HeuristicLabWorkingThread(options.InputFiles[i], options.Repetitions, finishedEvent, options.Verbose);
        hlThreads[i] = new Thread(new ThreadStart(hlWorkingThread[i].Run));
        hlThreads[i].Start();
      }

      WaitHandle.WaitAll(finishedWaitHandles);
      foreach (var wait in finishedWaitHandles) {
        wait.Dispose();
      }
    }
 public void Start(Options options) {
   foreach (var filePath in options.InputFiles) {
     Reevaluate(filePath, options.Timeout);
   }
 }
 public void Start(Options options) {
   foreach (var filePath in options.InputFiles) {
     Collect(filePath);
   }
 }