/// <summary>
 /// Initializes a new instance of the <see cref="StandardBreeder"/> class.
 /// </summary>
 /// <param name="properties">
 /// The properties. 
 /// </param>
 public StandardBreeder(EvolutionaryProperties properties)
 {
     this.properties = properties;
 }
        public TestFitnessFunction()
        {
            MetlinkDataProvider provider = new MetlinkDataProvider();

            EvolutionaryProperties properties = new EvolutionaryProperties();

            properties.DepartureTime = DateTime.Parse("27/06/2012 10:15 AM");
            properties.NetworkDataProviders = new [] {provider};
            properties.PointDataProviders = new [] {new WalkingDataProvider()};
            properties.FitnessFunction = new AlFitnessFunction(properties);
            properties.Database = new MySqlDatabase("20110606fordistributionforrmit");

            /*
            Route testRoute = new Route(-1)
                {

                    new MetlinkNode(19967,provider),
                    new MetlinkNode(19966,provider),
                    new MetlinkNode(19965,provider),
                    new MetlinkNode(9327,provider),
                    new MetlinkNode(9326,provider),
                    new MetlinkNode(9325,provider),
                    new MetlinkNode(9324,provider),
                    new MetlinkNode(9323,provider),
                    new MetlinkNode(20754,provider),
                    new MetlinkNode(9321,provider),
                    new MetlinkNode(9320,provider),
                    new MetlinkNode(9319,provider),
                    new MetlinkNode(9318,provider),
                    new MetlinkNode(9317,provider),
                    new MetlinkNode(9316,provider),
                    new MetlinkNode(9313,provider),
                    new MetlinkNode(9312,provider),
                    new MetlinkNode(20756,provider)
                };

            foreach (var node in testRoute)
            {
                node.RetrieveData();
                Console.WriteLine(node.ToString());
            }
            Fitness score = properties.FitnessFunction.GetFitness(testRoute);
            */
            Console.WriteLine("Press Enter.");
            Console.ReadLine();
            for (int i = 0; i < 12; i++)
            {
                properties.DepartureTime = DateTime.Parse("27/06/2012 6:00 PM").AddMinutes(i*5);

                var testRoute = new Route(-1)
                    {
                        new MetlinkNode(19965, provider),
                        new MetlinkNode(19966, provider),
                        new MetlinkNode(19967, provider),
                        new MetlinkNode(19968, provider),
                        new MetlinkNode(19969, provider),
                        new MetlinkNode(19970, provider),
                        new MetlinkNode(19971, provider),
                        new MetlinkNode(19972, provider),
                        new MetlinkNode(19973, provider),
                        new MetlinkNode(20041, provider),
                        new MetlinkNode(20040, provider),
                        new MetlinkNode(20039, provider),

                    };

                /**
                var testRoute = new Route(-1)
                    {
                        new MetlinkNode(9335 , provider),
            new MetlinkNode(9334 , provider),
            new MetlinkNode(9333 , provider),
            new MetlinkNode(9332 , provider),
            new MetlinkNode(9331 , provider),
            new MetlinkNode(9330 , provider),
            new MetlinkNode(9329 , provider),
            new MetlinkNode(9328 , provider),
            new MetlinkNode(9327 , provider),
            new MetlinkNode(9326 , provider),
            new MetlinkNode(9325 , provider),
            new MetlinkNode(9324 , provider),
            new MetlinkNode(9323 , provider),
            new MetlinkNode(20754 , provider),
            new MetlinkNode(9321 , provider),
            new MetlinkNode(9320 , provider),
            new MetlinkNode(9319 , provider),
            new MetlinkNode(9318 , provider),
            new MetlinkNode(9317 , provider),
            new MetlinkNode(9316 , provider),
            new MetlinkNode(9313 , provider),
            new MetlinkNode(9312 , provider),
            new MetlinkNode(20756 , provider),
            new MetlinkNode(9310 , provider),
            new MetlinkNode(20757 , provider),

                    };
               */
                var score = properties.FitnessFunction.GetFitness(testRoute);

                Console.WriteLine("Score: {0}", score);
                //Thread.Sleep(1000);
            }
            //properties.Database.Open();
            //properties.DataStructures = new DataStructures(properties);

            //EvolutionaryRoutePlanner planner = new EvolutionaryRoutePlanner(properties);
            // Stopwatch sw = Stopwatch.StartNew();
            // planner.Start();
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DFSRoutePlanner"/> class.
 /// </summary>
 /// <param name="properties">
 /// The properties.
 /// </param>
 public DFSRoutePlanner(EvolutionaryProperties properties)
 {
     this.properties = properties;
 }
        static bool RunServer(bool network)
        {
            //TODO: Move proxy into set command
            /*
             * UNCOMMENT FOR RMIT
            Console.WriteLine("Setting proxy settings...");
            ConnectionInfo.Proxy = new WebProxy(
                "http://aproxy.rmit.edu.au:8080", false, null, new NetworkCredential("s3229159", "MuchosRowlies1"));
            */

            Console.WriteLine("Loading CoreLibraries Assembly...");
            Assembly coreLibraries;
            try
            {
                try
                {
                    coreLibraries = Assembly.Load("RmitJourneyPlanner.CoreLibraries");
                }
                catch (Exception)
                {
                    coreLibraries = Assembly.LoadFile(Directory.GetCurrentDirectory() + "/RmitJourneyPlanner.CoreLibraries.dll");
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("There was an error loading the CoreLibraries assembly. Please check if 'RmitJourneyPlanner.CoreLibraries.dll' is present in the program directory.\nError Message: {0}", e.Message);
                return false;
            }

            string attributes = coreLibraries.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false).Cast<AssemblyFileVersionAttribute>().Aggregate("", (current, attribute) => current + attribute.Version);

            Console.WriteLine("Version: {0}",String.Join("\n",attributes));
            Console.WriteLine("Hooking into logging interface...");

            Logger.LogEvent += LoggerOnLogEvent;
            Logger.ProgressEvent += new ProgressEventHandler(Logger_ProgressEvent);

            /*
            Type[] types = coreLibraries.GetTypes();

            Console.WriteLine("Loading point data providers:");
            Type[] pdpTypes = getTypesImplimenting("IPointDataProvider", types);
            List<IPointDataProvider> pointDataProviders = new List<IPointDataProvider>();
            foreach (Type type in pdpTypes)
            {
                Console.WriteLine("--> {0} ", type.Name);
                IPointDataProvider pdp = type.InvokeMember("", BindingFlags.CreateInstance, null, null, null, null) as IPointDataProvider;
                if (pdp == null)
                {
                    Console.WriteLine("Error initializing the data provider.");
                }
                else
                {
                    pointDataProviders.Add(pdp);
                }
            }
            Console.WriteLine("Loading network data providers:");
            Type[] ndpTypes = getTypesImplimenting("INetworkDataProvider", types);
            List<INetworkDataProvider> networkDataProviders = new List<INetworkDataProvider>();
            foreach (Type type in ndpTypes)
            {
                Console.WriteLine("--> {0} ", type.Name);
                INetworkDataProvider ndp = type.InvokeMember("", BindingFlags.CreateInstance, null, null, null, null) as INetworkDataProvider;
                if (ndp == null)
                {
                    Console.WriteLine("Error initializing the data provider.");
                }
                else
                {
                    networkDataProviders.Add(ndp);
                }

            }
            */
            var properties = new EvolutionaryProperties();

            EvolutionaryRoutePlanner planner = null;
            bool run = true;
            StreamWriter resultWriter = null;
            string resultPath = "";
            Queue<string> commands = new Queue<string>();
            var results = new List<Result>();
            var loopCommands = new Queue<string>();
            var loopStack = new Stack<KeyValuePair<Queue<string>, int>>();
            int resultIndex = 0;
            //bool loop = false;

            Socket socket = null;

            if (network)
            {
                Console.WriteLine("Listening for socket connection.");
                TcpListener listener = new TcpListener(IPAddress.Loopback,3000);
                listener.Start();
                socket = listener.AcceptSocket();

            }

            while (run)
            {
                Console.Write("> ");

                string input = String.Empty;

                if (network)
                {
                    Byte[] buffer = new byte[1024];
                    socket.Receive(buffer);
                    BinaryReader reader = new BinaryReader(new MemoryStream(buffer));
                    input = reader.ReadString();
                }
                else
                {
                    if (filename == String.Empty)
                    {
                        input = Console.ReadLine().Trim();
                    }
                    else
                    {
                        input = "run " + filename;

                    }

                }

                RegexOptions options = RegexOptions.None;
                Regex regex = new Regex(@"[ ]{2,}", options);

                input = regex.Replace(input, @" ");

                foreach (var value in input.Split(';'))
                {
                    commands.Enqueue(value.Replace(";","").Trim());
                }
                bool echo = false;
                while (commands.Count > 0)
                {
                    string command = commands.Dequeue();
                    if (echo == false)
                    {
                        echo = true;
                    }
                    else
                    {
                        Console.WriteLine(command.Trim());
                    }
                    if (command.Length == 0)
                    {
                        continue;
                    }
                    if (command.ToLower() == "quit" || command.ToLower() == "exit")
                    {
                        run = false;
                        return true;
                    }

                    try
                    {

                        if (command.Contains("randomNode()"))
                        {

                        command = command.Replace(
                            "randomNode()",
                            ((MetlinkDataProvider)properties.NetworkDataProviders[0]).GetRandomNodeId().ToString(
                                CultureInfo.InvariantCulture));
                        }
                    string[] segments =  splitWithQuotes(command);
                        switch (segments[0].ToLower())
                        {
                            case "//":
                                break;

                            case "":
                                break;

                            case "help":
                                if (segments[1].ToLower() == "set")
                                {
                                    if (segments.Length == 2)
                                    {
                                        Console.WriteLine("   Help: set [parameter] [value]. - Sets a property.");
                                        Console.WriteLine(
                                            "   Here is a list of available properties. Type help set <property> for help on an individual property.");
                                        foreach (PropertyInfo p in typeof(EvolutionaryProperties).GetProperties())
                                        {
                                            if (p.CanWrite)
                                            {
                                                if (p.PropertyType.Name == "List`1")
                                                {
                                                    Type pType = p.PropertyType;

                                                    PropertyInfo pCount = pType.GetProperty("Count");
                                                    object o = p.GetValue(properties, null);
                                                    object count = pCount.GetValue(o, null);

                                                    Console.WriteLine(
                                                        "   {0} ({1}) = {2} ",
                                                        p.Name,
                                                        String.Format("List<{0}>", pType.Name),
                                                        count);
                                                }
                                                else
                                                {
                                                    string name = p.PropertyType.Name;
                                                    if (name.Contains("."))
                                                    {
                                                        name = name.Remove(
                                                            0, name.LastIndexOf(".", System.StringComparison.Ordinal));
                                                    }

                                                    Console.WriteLine(
                                                        "   {0} ({1}) = {2} ",
                                                        p.Name,
                                                        name,
                                                        p.GetValue(properties, null));
                                                }
                                            }
                                        }
                                    }
                                }
                                break;

                            case "loop":
                                string s;
                                int nestLevel = 0;
                                loopCommands.Clear();
                                while ((s = commands.Dequeue().ToLower()) != "end loop" || nestLevel > 0)
                                {
                                    string[] split = s.Split(' ');
                                    if (split.Length > 1 && split[0].Trim() == "loop")
                                    {
                                        nestLevel++;
                                    }
                                    if (s == "end loop")
                                    {
                                        nestLevel--;
                                    }
                                    loopCommands.Enqueue(s);
                                }
                                var loopedCommands = new Queue<string>();

                                for (int i = 0; i < int.Parse(segments[1]); i ++ )
                                {
                                     loopedCommands.Enqueue("// Loop " + i );
                                    foreach (var lcommand in loopCommands)
                                    {
                                        loopedCommands.Enqueue(lcommand);
                                    }

                                }
                                foreach (var mcommand in commands)
                                {
                                    loopedCommands.Enqueue(mcommand);
                                }

                                commands = loopedCommands;
                                break;

                            case "set":
                                if (segments[2].ToLower() == "new")
                                {
                                    ///Console.WriteLine("Creating new instance...");
                                    PropertyInfo info = typeof(EvolutionaryProperties).GetProperty(segments[1]);
                                    if (info == null)
                                    {
                                        throw new Exception("That property does not exist.");
                                    }

                                    string typeName = segments[3];
                                    Type type = searchForType(typeName, coreLibraries);
                                    object o = null;
                                    if (segments.Length == 4)
                                    {
                                        try
                                        {
                                            o = type.InvokeMember("", BindingFlags.CreateInstance, null, null, null);

                                        }
                                        catch( MissingMethodException )
                                        {
                                            o = type.InvokeMember(
                                             "", BindingFlags.CreateInstance, null, null, new object[] { properties });
                                        }
                                        catch (Exception e)
                                        {
                                            Logger.Log(typeof(Program), "Warning: Exception on instance creation: " + e.Message);
                                            if (e.InnerException != null)
                                            {
                                                Logger.Log(
                                                    typeof(Program),
                                                    "-------> Inner exception: " + e.InnerException.Message);

                                                if (e.InnerException.InnerException != null)
                                                {
                                                    Logger.Log(
                                                        typeof(Program),
                                                        "-------> ------->Inner inner exception: " + e.InnerException.InnerException.Message);
                                                }
                                            }
                                        }

                                    }
                                    else
                                    {
                                        int noParam = segments.Length - 4;
                                        bool created = false;
                                        foreach (var constructor in type.GetConstructors())
                                        {
                                            //int count = 0;

                                            ParameterInfo[] infos = constructor.GetParameters();
                                            if (infos.Length == noParam)
                                            {
                                                var p = new List<object>();

                                                for (int z = 4; z < segments.Length; z++)
                                                {
                                                    if (segments[z].ToLower() == "metlinkprovider")
                                                    {
                                                        p.Add(properties.NetworkDataProviders[0]);
                                                    }
                                                    else
                                                    {
                                                        p.Add(Convert.ChangeType(segments[z], infos[z - 4].ParameterType));

                                                    }
                                                }

                                                o = type.InvokeMember(
                                                    "", BindingFlags.CreateInstance, null, null, p.ToArray());
                                                created = true;
                                            }
                                        }
                                        if (!created)
                                        {
                                            throw new Exception("Error executing constructor / Unable to find a constuctor with those values.");
                                        }
                                    }

                                    //PropertyInfo info = typeof(EvolutionaryProperties).GetProperty(segments[1]);
                                    if (info.PropertyType.Name == "List`1")
                                    {
                                        Type listType = info.PropertyType;

                                        object list = info.GetValue(
                                            properties, BindingFlags.GetProperty, null, null, null);
                                        MethodInfo methodInfo = listType.GetMethod("Add");
                                        methodInfo.Invoke(
                                            list, BindingFlags.InvokeMethod, null, new object[] { o }, null);
                                    }
                                    else
                                    {
                                        typeof(EvolutionaryProperties).GetProperty(segments[1]).SetValue(
                                            properties, o, BindingFlags.SetProperty, null, null, null);
                                    }
                                }
                                else if (segments[1].ToLower() == "resultoutput")
                                {
                                    if (File.Exists(segments[2]))
                                    {
                                        Console.WriteLine("   Warning: File exists and will be overwritten.");
                                    }
                                    resultWriter = new StreamWriter(segments[2], false);
                                    resultPath = segments[2];
                                }
                                else
                                {
                                    string propertyName = segments[1];
                                    string value = segments[2];

                                    PropertyInfo info = typeof(EvolutionaryProperties).GetProperty(propertyName);
                                    if (info.PropertyType.IsValueType)
                                    {
                                        object o = Convert.ChangeType(value, info.PropertyType);
                                        typeof(EvolutionaryProperties).GetProperty(propertyName).SetValue(
                                            properties, o, BindingFlags.SetProperty, null, null, null);
                                    }
                                    else
                                    {
                                        Console.WriteLine(
                                            "   Only value types (int, string) can be used with this property. Try the new keyword to create an instance.");
                                    }
                                }

                                break;

                            case "run":
                                try
                                {
                                    using (var reader = new StreamReader(segments[1]))
                                    {
                                        var newQueue = new Queue<string>();
                                        string script = reader.ReadToEnd();
                                        foreach (var c in script.Split(';'))
                                        {
                                            newQueue.Enqueue(c.Replace(";", "").Trim());
                                        }
                                        foreach (var c in commands)
                                        {
                                            newQueue.Enqueue(c);
                                        }

                                        commands = newQueue;
                                    }
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("Error running script: {0}", e.Message);
                                }

                                break;

                            case "dump":
                                if (segments[1].ToLower() == "population")
                                {
                                    resultWriter.WriteLine("\n[Population Dump]");
                                    foreach (var critter in planner.Result.Population)
                                    {
                                        string line = critter.Route.Aggregate(
                                            "", (current, node) => current + (node.Node.Id + ","));
                                        resultWriter.WriteLine(line);
                                    }
                                    resultWriter.WriteLine("[End Population Dump]");
                                }
                                if (segments[1].ToLower() == "averageresults")
                                {
                                    int n = Int32.Parse(segments[2]);

                                    for (int i = 0; i < n; i++)
                                    {
                                        Result average = default(Result);
                                        for (int j = 0; j < results.Count / n; j++)
                                        {
                                            average.AverageFitness += results[i + (j*n)].AverageFitness;
                                            average.DiversityMetric += results[i + (j*n)].DiversityMetric;
                                            average.MinimumFitness += results[i + (j*n)].MinimumFitness;
                                            average.Totaltime += results[i + (j*n)].Totaltime;

                                        }
                                        average.AverageFitness /= (results.Count / (double) n);
                                        average.DiversityMetric /= (results.Count / (double)n);
                                        average.MinimumFitness /= (results.Count / (double) n);
                                        average.Totaltime = new TimeSpan(average.Totaltime.Ticks / (results.Count / n));
                                        if (resultWriter != null)
                                        {
                                                resultWriter.WriteLine(average.ToString());
                                        }
                                    }
                                    results.Clear();

                                }
                                if (segments[1].ToLower() == "htmlmap")
                                {
                                    Tools.SavePopulation(planner.Population.GetRange(0,1),0,properties,resultPath+ ".html");
                                }

                                if (segments[1].ToLower() == "saveline")
                                {
                                    if (resultWriter.BaseStream.CanWrite)
                                    {
                                        resultWriter.Close();
                                    }
                                    StreamReader reader = new StreamReader(resultPath);
                                    string text = reader.ReadToEnd().Trim();
                                    reader.Close();
                                    string[] lines = text.Split('\n');

                                    try
                                    {
                                        if (resultIndex < lines.Length)
                                        {
                                            if (resultIndex < results.Count)
                                            {
                                                lines[resultIndex] = lines[resultIndex].Trim() + ","
                                                                     + results[resultIndex].AverageFitness;
                                            }
                                            else
                                            {
                                                lines[resultIndex] = lines[resultIndex].Trim() + ","
                                                                     + "-1";
                                            }
                                            resultWriter = new StreamWriter(resultPath, false);
                                            string st = String.Join("\n", lines);
                                            resultWriter.Write(st);
                                        }
                                        else
                                        {
                                            resultWriter = new StreamWriter(resultPath, true);
                                            if (resultIndex < results.Count)
                                            {
                                                resultWriter.WriteLine(results[resultIndex].AverageFitness);
                                            }
                                            else
                                            {
                                                resultWriter.WriteLine("-1");
                                            }
                                        }
                                    }
                                    catch (Exception)
                                    {

                                        Console.WriteLine("Error writing things...");
                                    }

                                }

                                break;

                            case "start":
                                //try
                                try
                                {
                                    planner = new EvolutionaryRoutePlanner(properties);
                                    planner.Start();
                                    results.Clear();
                                    results.Add(planner.Result);

                                }
                                catch (Exception e)
                                {
                                    var r = new Result { AverageFitness = new Fitness() };
                                    results.Add(r);
                                    Console.WriteLine("   Error starting travel planner:\n   {0}\n   {1}", e.Message, e.StackTrace);
                                }

                                resultIndex = 0;

                                /*
                                if (resultWriter != null)
                                {
                                    resultWriter.WriteLine(planner.Result.ToString());
                                }
                                 */
                                /*
                                catch (Exception e)
                                {
                                    Console.WriteLine("   Error starting travel planner:\n   {0}\n   {1}", e.Message,e.StackTrace);
                                }
                                */

                                break;

                            case "disable":
                                if (segments[1] == "log")
                                {
                                    Logger.LogEvent -= LoggerOnLogEvent;
                                }
                                break;

                            case "enable":
                                if (segments[1] == "log")
                                {
                                    Logger.LogEvent += LoggerOnLogEvent;
                                }

                                break;

                            case "step":
                                try
                                {
                                    int iterations = 1;
                                    if (segments.Length > 1)
                                    {
                                        int i;
                                        if (Int32.TryParse(
                                            segments[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out i))
                                        {
                                            iterations = i;
                                        }
                                    }

                                    for (int i = 0; i < iterations; i++)
                                    {
                                        planner.SolveStep();
                                        /*
                                        if (resultWriter != null)
                                        {
                                            resultWriter.WriteLine(planner.Result.ToString());
                                        }
                                         * */
                                        results.Add(planner.Result);
                                    }

                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("   Error stepping travel planner:\n   {0}\n   {1}", e.Message, e.StackTrace);
                                    var r = new Result { AverageFitness = new Fitness()};
                                    results.Add(r);
                                }

                                resultIndex++;

                                break;
                            default:
                                throw new Exception("   Command not recognised.");
                        }
                    }
                    catch(TargetInvocationException e)
                    {
                        Console.WriteLine("   There was an error parsing your command.");
                        Console.WriteLine("      There was an error invoking the new instance.\n      {0}", e.InnerException.Message);

                    }
                    catch (IndexOutOfRangeException)
                    {
                        Console.WriteLine(
                            "   There was an error parsing your command. Type help for a list of commands.");
                        //commands.Clear();

                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(
                            "   There was an error parsing your command. \n {0} \nType help for a list of commands.",
                            e.Message);
                        if (e.InnerException != null)
                        {
                            Console.WriteLine("    Inner Exception Message: " + e.InnerException.Message);
                        }
                        //commands.Clear();

                    }

                }

            }

            return true;
        }
        public void Test()
        {
            int iterations = 20;
            INetworkDataProvider metlinkProvider = new MetlinkDataProvider();

            //http://ptv.vic.gov.au/stop/view/StopID

            var testRoutes2 = new[,]
                {
                    { new MetlinkNode(19965, metlinkProvider), new MetlinkNode(19879, metlinkProvider) },
                    { new MetlinkNode(12018, metlinkProvider), new MetlinkNode(18475, metlinkProvider) },
                    { new MetlinkNode(19965, metlinkProvider), new MetlinkNode(19842, metlinkProvider) }
                };

            var testRoutes = new[,]
                {
                    // Long inter-suburban routes
                    {
                        new MetlinkNode(19965, metlinkProvider),
                        new MetlinkNode(19879, metlinkProvider)
                    }, // Coburg - Ringwood
                    {
                        new MetlinkNode(20005, metlinkProvider),
                        new MetlinkNode(19855, metlinkProvider)
                    }, // Epping - Frankston
                    {
                        new MetlinkNode(19990, metlinkProvider),
                        new MetlinkNode(19921, metlinkProvider)
                    }, // Hurstbridge - Werribee
                    {
                        new MetlinkNode(19844, metlinkProvider),
                        new MetlinkNode(20000, metlinkProvider)
                    }, // Belgrave - Watergardens
                    {
                        new MetlinkNode(19886, metlinkProvider),
                        new MetlinkNode(40221, metlinkProvider)
                    }, // Cranbourne - Craigieburn

                    // Lateral inter-suburban routes.
                    {
                        new MetlinkNode(19965, metlinkProvider),
                        new MetlinkNode(19935, metlinkProvider)
                    }, // Coburg - Heidelberg
                    {
                        new MetlinkNode(19965, metlinkProvider),
                        new MetlinkNode(628, metlinkProvider)
                    }, // Coburg - Kew (Wilsmear/Grandview)
                    {
                        new MetlinkNode(19990, metlinkProvider),
                        new MetlinkNode(19246, metlinkProvider)
                    },
                    // East Kew Terminus - Box Hill (r202)
                    {
                        new MetlinkNode(12018, metlinkProvider),
                        new MetlinkNode(18475, metlinkProvider)
                    }, // Yarravile - Highpoint (r223)
                    {
                        new MetlinkNode(4808, metlinkProvider),
                        new MetlinkNode(19649, metlinkProvider)
                    }, // Greensborough - Boxhill

                    // Inner-city routes.
                    {
                        new MetlinkNode(19843, metlinkProvider),
                        new MetlinkNode(22180, metlinkProvider)
                    }, // Parliament - Southern Cross
                    {
                        new MetlinkNode(17882, metlinkProvider),
                        new MetlinkNode(19841, metlinkProvider)
                    },
                    // 9-Spring St/Bourke St  - Flagstaff
                    {
                        new MetlinkNode(19489, metlinkProvider),
                        new MetlinkNode(19973, metlinkProvider)
                    }, // Melbourne Uni - North Melbourne
                    {
                        new MetlinkNode(18034, metlinkProvider),
                        new MetlinkNode(17901, metlinkProvider)
                    },
                    // 2-King St/La Trobe St - Melbourne Town Hall/Collins St
                    {
                        new MetlinkNode(18450, metlinkProvider),
                        new MetlinkNode(19594, metlinkProvider)
                    },
                    // Casino - Royal Childrens Hospital/Flemington Rd

                    // Commuter Routes
                    {
                        new MetlinkNode(19965, metlinkProvider),
                        new MetlinkNode(19842, metlinkProvider)
                    }, // Coburg - Melbourne Central
                    {
                        new MetlinkNode(19876, metlinkProvider),
                        new MetlinkNode(19841, metlinkProvider)
                    }, // Lilydale  - Flagstaff
                    {
                        new MetlinkNode(19489, metlinkProvider),
                        new MetlinkNode(19921, metlinkProvider)
                    }, // Werribee - North Melbourne
                    {
                        new MetlinkNode(20005, metlinkProvider),
                        new MetlinkNode(19843, metlinkProvider)
                    }, // Epping - Parliament
                    {
                        new MetlinkNode(19855, metlinkProvider),
                        new MetlinkNode(19854, metlinkProvider)
                    } // Frankston - Flinders St

                };
            bool first = true;
            DateTime time = DateTime.Parse("8:00 AM 7/05/2012");

            bool cont = true;

            while (cont)
            {
                foreach (SearchType searchType in Enum.GetValues(typeof(SearchType)))
                {
                    if (searchType == SearchType.DFS_BiDir || searchType == SearchType.DFS_Standard)
                        continue;

                    //foreach (bool bidir in new[] { true, false })
                    {
                        for (int i = 0; i < testRoutes.GetLength(0); i++)
                        {

                            //try
                            {
                                testRoutes[i, 0].RetrieveData();
                                testRoutes[i, 1].RetrieveData();

                                EvolutionaryProperties properties = new EvolutionaryProperties();
                                properties.NetworkDataProviders = new [] {metlinkProvider};
               						 properties.PointDataProviders = new [] {new WalkingDataProvider()};
                                properties.ProbMinDistance = 0.7;
                                properties.ProbMinTransfers = 0.2;
                                properties.MaximumWalkDistance = 1.5;
                                properties.PopulationSize = 100;
                                properties.MaxDistance = 0.5;
                                properties.DepartureTime = time;
                                properties.NumberToKeep = 25;
                                properties.MutationRate = 0.1;
                                properties.CrossoverRate = 0.7;
                                //properties.Bidirectional = bidir;
                                //properties.RouteGenerator = new AlRouteGenerator(properties);
                                properties.SearchType = SearchType.Greedy_BiDir;
                                properties.RouteGenerator = new DFSRoutePlanner(properties);
                                properties.Mutator = new StandardMutator(properties);
                                properties.Breeder = new StandardBreeder(properties);
                                properties.FitnessFunction = new AlFitnessFunction(properties);
                                properties.Database = new MySqlDatabase("20110606fordistributionforrmit");
                                properties.Destination = testRoutes[i, 0];
                                properties.Origin = testRoutes[i, 1];
                                properties.Destination.RetrieveData();

                                properties.Database.Open();
                                //properties.DataStructures = new DataStructures(properties);

                                var planner = new EvolutionaryRoutePlanner(properties);
                                Stopwatch sw = Stopwatch.StartNew();
                                planner.Start();

                                StreamWriter writer =
                                    new StreamWriter(
                                        "results/" + searchType + "-" + testRoutes[i, 0].Id + "-"  + testRoutes[i, 1].Id + ".csv",
                                        true);
                                writer.WriteLine(
                                    "[New iteration {0}-{1} ({2}-{3}) {4} @ {5}]",
                                    testRoutes[i, 0].Id,
                                    testRoutes[i, 1].Id,
                                    testRoutes[i, 0].StopSpecName,
                                    testRoutes[i, 1].StopSpecName,
                                    searchType,
                                    DateTime.Now.ToString(CultureInfo.InvariantCulture));

                                Console.WriteLine(
                                    "[New iteration {0}-{1} ({2}-{3}) {4} @ {5}]",
                                    testRoutes[i, 0].Id,
                                    testRoutes[i, 1].Id,
                                    testRoutes[i, 0].StopSpecName,
                                    testRoutes[i, 1].StopSpecName,
                                    searchType,
                                    DateTime.Now.ToString(CultureInfo.InvariantCulture));

                                writer.WriteLine(
                                    "Average UnifiedFitnessScore, Minimum Fitenss, Diversity Metric, Total Time (Iteration), Total Time (Test),Iteration number");

                                this.writeInfo(writer, planner, sw.Elapsed, 0);

                                for (int j = 0; j < 99; j++)
                                {
                                    planner.SolveStep();
                                    this.writeInfo(writer, planner, sw.Elapsed, j + 1);
                                }
                                writer.WriteLine("Path: " + String.Join(",",planner.Result.BestPath));
                                writer.Close();
                                properties.Database.Close();
                            }
                                /*
                            catch (Exception e)
                            {
                                Console.WriteLine("Exception!: {0} ({1}). Writing to error log...", e, e.Message);
                                StreamWriter writer = new StreamWriter("error.log", true);
                                writer.WriteLine(
                                    "[{0}] Exception!: {1} ({2}).\n{3}",
                                    DateTime.Now.ToString(CultureInfo.InvariantCulture),
                                    e,
                                    e.Message,
                                    e.StackTrace);
                                writer.WriteLine(
                                    "[Last error thrown on: {0}-{1} ({2}-{3}) {4} @ {5}]",
                                    testRoutes[i, 0].Id,
                                    testRoutes[i, 1].Id,
                                    testRoutes[i, 0].StopSpecName,
                                    testRoutes[i, 1].StopSpecName,
                                    searchType,
                                    DateTime.Now.ToString(CultureInfo.InvariantCulture));
                                writer.Close();
                                throw;
                            }
                                 * */

                        }
                    }
                }
                var reader = new StreamReader("cont.txt");
                string result = reader.ReadToEnd().Trim();
                switch (result)
                {
                    case "yes":
                        cont = true;
                        break;
                    case "no":
                        cont = false;
                        break;
                    default:
                        Console.WriteLine("Cant read {0}" , ((FileStream)reader.BaseStream).Name);
                        break;
                }
                reader.Close();

            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="AlFitnessFunction"/> class.
 /// </summary>
 /// <param name="properties">
 /// The properties. 
 /// </param>
 public AlFitnessFunction(EvolutionaryProperties properties)
 {
     this.properties = properties;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="StandardMutator"/> class.
 /// </summary>
 /// <param name="properties">
 /// The properties. 
 /// </param>
 public StandardMutator(EvolutionaryProperties properties)
 {
     this.properties = properties;
 }