private static bool LoadConditionsFromCache(ConditionEntry[] defaultEntries, Dictionary <Model, ConditionEntry[]> extraConditionsByModel)
        {
            if (File.Exists(CompiledConditionsCacheFilePath))
            {
                Game.LogTrivial("Conditions cache file exists");

                CompiledConditionsCacheFile cacheFile = new CompiledConditionsCacheFile();
                if (cacheFile.Read(CompiledConditionsCacheFilePath))
                {
                    if (cacheFile.CompareXmlFiles(CompiledConditionsCacheFile.GetCurrentXmlFiles()))
                    {
                        List <string> names = new List <string>();
                        if (defaultEntries != null)
                        {
                            foreach (ConditionEntry entry in defaultEntries)
                            {
                                string name = entry.Name;
                                names.Add(name);
                            }
                        }
                        if (extraConditionsByModel != null)
                        {
                            foreach (KeyValuePair <Model, ConditionEntry[]> extraEntriesPair in extraConditionsByModel)
                            {
                                foreach (ConditionEntry entry in extraEntriesPair.Value)
                                {
                                    string name = GetMethodNameFor(extraEntriesPair.Key, entry.Name);
                                    names.Add(name);
                                }
                            }
                        }

                        Type type = cacheFile.LoadAssembly().GetType(ConditionCodeClassName);
                        foreach (string name in names)
                        {
                            conditionsByName.Add(name, (ConditionDelegate)type.GetMethod(name).CreateDelegate(typeof(ConditionDelegate)));
                        }
                        Game.LogTrivial("Loaded conditions from cache");

                        return(true);
                    }
                    else
                    {
                        Game.LogTrivial("There has been changes to the XML files since the cache was made, deleting cache");
                        File.Delete(CompiledConditionsCacheFilePath);
                    }
                }
                else
                {
                    Game.LogTrivial("Failed to read cache, deleting cache");
                    File.Delete(CompiledConditionsCacheFilePath);
                }

                cacheFile = null;
            }

            return(false);
        }
        private static void CompileConditions(ConditionEntry[] defaultEntries, Dictionary <Model, ConditionEntry[]> extraConditionsByModel)
        {
            Game.LogTrivial("Compiling conditions");

            StringBuilder methods      = new StringBuilder();
            List <string> entriesNames = new List <string>();

            if (defaultEntries != null)
            {
                foreach (ConditionEntry entry in defaultEntries)
                {
                    string name = entry.Name;
                    methods.AppendFormat(ConditionMethodCodeTemplate, entry.Name, entry.Code);
                    entriesNames.Add(name);
                }
            }
            if (extraConditionsByModel != null)
            {
                foreach (KeyValuePair <Model, ConditionEntry[]> extraEntriesPair in extraConditionsByModel)
                {
                    foreach (ConditionEntry entry in extraEntriesPair.Value)
                    {
                        string name = GetMethodNameFor(extraEntriesPair.Key, entry.Name);
                        methods.AppendFormat(ConditionMethodCodeTemplate, name, entry.Code);
                        entriesNames.Add(name);
                    }
                }
            }

            string code = String.Format(ConditionBaseCodeTemplate, methods.ToString());

            Game.LogTrivialDebug(code);

            CompilerParameters parameters = new CompilerParameters();

            parameters.IncludeDebugInformation = false;
            parameters.GenerateInMemory        = false;
            parameters.GenerateExecutable      = false;
            parameters.CompilerOptions         = "/optimize /platform:x64";
            parameters.ReferencedAssemblies.AddRange(new[] { "mscorlib.dll", "System.dll", "System.Core.dll", "System.Dynamic.dll", "System.Windows.Forms.dll", "System.Drawing.dll", "Microsoft.CSharp.dll", typeof(Vehicle).Assembly.Location });
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerResults    results  = provider.CompileAssemblyFromSource(parameters, code);

            if (results.Errors.HasErrors)
            {
                Game.LogTrivial("   Compilation failed");
                Game.LogTrivial("   Errors:");
                foreach (CompilerError e in results.Errors)
                {
                    Game.LogTrivial("       " + e.ToString());
                }
            }
            else
            {
                Type type = results.CompiledAssembly.GetType(ConditionCodeClassName);
                foreach (string name in entriesNames)
                {
                    conditionsByName.Add(name, (ConditionDelegate)type.GetMethod(name).CreateDelegate(typeof(ConditionDelegate)));
                }

                Game.LogTrivial("Conditions compiled, saving to cache");
                new CompiledConditionsCacheFile(CompiledConditionsCacheFile.GetCurrentXmlFiles(), results.CompiledAssembly).Write(CompiledConditionsCacheFilePath);
            }
        }