private bool ScriptedResearch(string command1, string command2, string modifier)
        {
            ConcurrentBag<Technology> AvailableTechsbag = new ConcurrentBag<Technology>();

            foreach (KeyValuePair<string, Ship_Game.Technology> Technology in ResourceManager.TechTree)
            {

                TechEntry tech = null;// new TechEntry();
                bool techexists = this.empire.GetTDict().TryGetValue(Technology.Key, out tech);
                if (!techexists || tech == null)
                    continue;
                Technology technology = tech.GetTech();
                if (tech.Unlocked
                    || !this.empire.HavePreReq(Technology.Key)
                    || (Technology.Value.Secret && !tech.Discovered)
                    || technology.BuildingsUnlocked.Where(winsgame => ResourceManager.BuildingsDict[winsgame.Name].WinsGame == true).Count() > 0
                    //|| !tech.shipDesignsCanuseThis
                    //|| (tech.shipDesignsCanuseThis && technology.ModulesUnlocked.Count > 0 && tech.shipDesignsCanuseThis && technology.HullsUnlocked.Count ==0
                    //&& !this.empire.WeCanUseThisNow(tech.GetTech()))
                    )
                {

                    continue;
                }

                AvailableTechsbag.Add(Technology.Value);
            }

            if (AvailableTechsbag.Count <= 0)
            {
                return false;
            }
            List<Technology> AvailableTechs = AvailableTechsbag.ToList();//new List<Technology>();
            List<string> useableTech = new List<string>();

            string researchtopic = "";
            TechnologyType techtype;

            #region hull checking.

            string BestShip = ""; //this.BestCombatShip;
            float bestShipStrength = 0f;

            float moneyNeeded = 0;

            float money = this.empire.EstimateIncomeAtTaxRate(.55f -((int)Ship.universeScreen.GameDifficulty *.05f) )+ this.empire.GetTotalShipMaintenance();
            if (this.BestCombatShip != ""
               // && weCanBuildCurrentHull
                && this.empire.ShipsWeCanBuild.Contains(this.BestCombatShip)
                )
            {
                //
                this.BestCombatShip = "";
            }
            //    if (string.IsNullOrEmpty(this.BestCombatShip) ||  (money <= moneyNeeded || AvailableTechs.Where(tech => tech.TechnologyType == TechnologyType.ShipHull && tech.Cost / this.empire.Research < 200).Count() < 1))

            List<string> unlockedTech = new List<string>();
            foreach (KeyValuePair<string, TechEntry> techs in this.empire.TechnologyDict)
            {
                if (techs.Value.Unlocked)
                    unlockedTech.Add(techs.Key);
            }

            #region shipTechPicker
            Ship ship;

            bool CanNotSupportNewHull = false;
            if (!string.IsNullOrEmpty(this.BestCombatShip))
            {

                if (ResourceManager.ShipsDict.TryGetValue(this.BestCombatShip, out ship))
                {

                    int techCount = ship.shipData.techsNeeded.Count;
                    CanNotSupportNewHull = ship.GetMaintCost(this.empire) * 10 >money;
                    bool flag=false;
                    foreach (string shiptech in ship.shipData.techsNeeded)
                    {
                        if (unlockedTech.Contains(shiptech))
                            continue;
                        flag = true;
                        break;
                    }
                    if(!flag)
                    {
                        this.BestCombatShip = string.Empty;
                    }

                }
            }

                int BestShipTechCost = 0;
                //if (string.IsNullOrEmpty(this.BestCombatShip) )//|| CanNotSupportNewHull)
                foreach (KeyValuePair<string, Ship> wecanbuildit in ResourceManager.ShipsDict.OrderBy(techcost => techcost.Value.shipData != null ? techcost.Value.shipData.TechScore : 0)) // techcost.Value.BaseStrength)) //techcost.Value.shipData != null ? techcost.Value.shipData.techsNeeded.Count : 0))// // shipData !=null? techcost.Value.shipData.TechScore:0))   //Value.shipData.techsNeeded.Count:0))
                {
                    //if (this.BestCombatShip == wecanbuildit.Key )
                    //    continue;
                    bool test;
                    //if (!this.empire.GetHDict().TryGetValue(wecanbuildit.Value.shipData.Hull, out test))
                    //    continue;
                    //if (!test)
                    //    continue;
                    ship= wecanbuildit.Value;
                    if (ship.shipData == null)
                        continue;
                    if (ship.BaseStrength < 1f)
                        continue;
                    Ship_Game.ShipRole roles;
                    if (!ResourceManager.ShipRoles.TryGetValue(ship.Role, out roles)
                        || roles==null || roles.Protected)//  [ship.Role].Protected )//  ship.Role == "prototype")
                        continue;

                    test = false;

                    if (ship.shipData.ShipStyle != this.empire.data.Traits.ShipType
                        && (this.empire.GetHDict().TryGetValue(ship.shipData.Hull, out test) && test==true)==false)
                        continue;
                    test = false;
                    if (this.empire.ShipsWeCanBuild.Contains(wecanbuildit.Key) )//this.empire.GetHDict()[ship.shipData.Hull] ||
                        continue;
                    int techCost = ship.shipData.techsNeeded.Count;
                    if (techCost == 0)
                        continue;

                    int trueTechcost = techCost;
                    //if (ship.shipData.Role == currentHull)

                    //if (AvailableTechs.Where(tech => tech.TechnologyType == TechnologyType.ShipHull && ship.shipData.techsNeeded.Contains(tech.UID)).Count() < 1)
                    //    continue;
                    {
                        moneyNeeded = ship.GetMaintCost(this.empire) * 5;

                        foreach (string shipTech in ship.shipData.techsNeeded)
                        {

                            if (!test && !unlockedTech.Contains(shipTech))
                            {
                                test = true;
                            }
                            //if (!AvailableTechs.Where(tech => tech.TechnologyType == TechnologyType.ShipHull && tech.uid Contains(shipTech))
                            //{
                            //    //test = false;
                            //    //break;

                            //}
                            //if (!string.IsNullOrEmpty(this.BestCombatShip)  )
                            {
                                TechEntry generalTech;

                                if (this.empire.TechnologyDict.TryGetValue(shipTech, out generalTech))
                                {
                                    Technology hull = generalTech.GetTech();
                                    if (generalTech.Unlocked)
                                    {
                                        techCost--;
                                        trueTechcost--;
                                        continue;
                                    }
                                    else if ((hull.RaceRestrictions.Count > 0 && hull.RaceRestrictions.Where(restrict => restrict.ShipType == this.empire.data.Traits.ShipType).Count() ==0 )
                                        || (hull.RaceRestrictions.Count == 0 && hull.Secret && !hull.Discovered) )

                                    {
                                        test = false;
                                        break;
                                    }
                                    else if (generalTech.GetTech().TechnologyType == TechnologyType.ShipGeneral)
                                    {
                                        techCost--;
                                        continue;
                                    }
                                    //if (hull.TechnologyType == TechnologyType.ShipHull)
                                    {

                                        //if (!this.empire.TechnologyDict.ContainsKey(  !unlockedTech.Contains(hull.UID))
                                        //{
                                        //    test = false;
                                        //    break;
                                        //}
                                        //foreach (Technology.UnlockedHull uhull in hull.HullsUnlocked)
                                        //{

                                        //}
                                        //if (hull.unlockBattleships)
                                        //    moneyNeeded = 80;
                                        //else if (hull.unlockCruisers)
                                        //    moneyNeeded = 60;
                                        //else if (hull.unlockFrigates)
                                        //    moneyNeeded = 25;
                                        //else if (hull.unlockCorvettes)
                                        //    moneyNeeded = 10;
                                        if (money / moneyNeeded < 1 )
                                        {
                                            test = false;
                                            break;
                                            //techCost += 100;
                                        }
                                        if (hull.Cost / (this.empire.Research + 1) > 500)
                                        {
                                            techCost += 2; //(int)(hull.Cost / (150 * (this.empire.Research + 1)));
                                        }
                                        else if (hull.Cost / (this.empire.Research + 1) > 150)
                                            techCost += 1;

                                    }
                                    if (!test)
                                        continue;
                                }
                                else
                                    test = false;
                            }
                        }
                        if (!test)
                        {
                            if (ship.Name == this.BestCombatShip)
                                this.BestCombatShip = string.Empty;
                            ship = null;
                            continue;
                        }
                        useableTech.AddRange(ship.shipData.techsNeeded);
                        if (trueTechcost == 0)
                        {
                            System.Diagnostics.Debug.WriteLine("skipped: " + ship.Name);
                            if (ship.Name == this.BestCombatShip)
                                this.BestCombatShip = string.Empty;
                            ship = null;
                            continue;
                        }
                        if (string.IsNullOrEmpty(BestShip) ||(bestShipStrength < ship.BaseStrength &&  BestShipTechCost >= techCost)) //BestShipTechCost == 0 ||
                        {
                            bestShipStrength = ship.BaseStrength;
                            BestShip = wecanbuildit.Key;
                            BestShipTechCost = techCost;
                            System.Diagnostics.Debug.WriteLine("Choosing Best Ship Tech: " + this.empire.data.Traits.ShipType + " -Ship: " + BestShip + " -TechCount: " + trueTechcost +"/"+techCost);
                        }

                    }
                }
                if (string.IsNullOrEmpty(this.BestCombatShip) )//|| CanNotSupportNewHull)
                this.BestCombatShip = BestShip;
                //if (string.IsNullOrEmpty(this.BestCombatShip) && CanNotSupportNewHull)
                //{
                //    string[] remove =modifier.Split(':');
                //    foreach(string techtypeTemp in remove)
                //    {
                //        foreach(TechnologyType x in Enum.GetValues(typeof(TechnologyType)))
                //        {
                //            if(x== TechnologyType.ShipDefense || x==TechnologyType.ShipGeneral || x==TechnologyType.ShipHull || x==TechnologyType.ShipWeapons)
                //            {
                //                modifier= modifier.Replace(techtypeTemp,string.Empty);
                //            }
                //        }
                //    }
                //}

                System.Diagnostics.Debug.WriteLine("This is Best Ship Tech: " + this.empire.data.Traits.ShipType + " -Ship: " + this.BestCombatShip);//+ " -TechCount: " + ship.shipData.techsNeeded.Count);
                if (modifier == "TECH:ShipWeapons:ShipDefense:ShipGeneral:ShipHull")
                {
                    command2 = "SHIPTECH";

                }
                if (command2 != "SHIPTECH")
                {

                    if (!this.empire.ShipsWeCanBuild.Contains(this.BestCombatShip))
                    {
                        //Ship ship;
                        if (ResourceManager.ShipsDict.TryGetValue(this.BestCombatShip, out ship) && ship != null && ship.shipData != null && ship.shipData.techsNeeded.Count > 0)
                        {
                            System.Diagnostics.Debug.WriteLine("This is Best Ship Tech: " + this.empire.data.Traits.ShipType + " -Ship: " + ship.Name + " -TechCount: " + ship.shipData.techsNeeded.Where(Notunlocked=> !unlockedTech.Contains(Notunlocked)).Count());
                            List<Technology> techPurge = new List<Technology>();
                            foreach (Technology shiptech in AvailableTechs)
                            {
                                if (shiptech.TechnologyType == TechnologyType.ShipDefense || shiptech.TechnologyType == TechnologyType.ShipGeneral || shiptech.TechnologyType == TechnologyType.ShipWeapons || shiptech.TechnologyType == TechnologyType.ShipHull)
                                {
                                    //if (!weCanBuildCurrentHull)
                                    {
                                        if (!ship.shipData.techsNeeded.Contains(shiptech.UID))
                                            techPurge.Add(shiptech);
                                    }

                                }
                            }

                            foreach (Technology purge in techPurge)
                            {
                                AvailableTechs.Remove(purge);
                            }
                        }
                    }
                    else
                    {
                        if (useableTech.Count > 0)
                            AvailableTechs = AvailableTechs.Where(shiptech => (
                                shiptech.TechnologyType != TechnologyType.ShipDefense
                                && shiptech.TechnologyType != TechnologyType.ShipGeneral
                                && shiptech.TechnologyType != TechnologyType.ShipWeapons
                                && shiptech.TechnologyType != TechnologyType.ShipHull)
                                || useableTech.Contains(shiptech.UID)).ToList();
                    }
                }
            #endregion
            #endregion
            float CostNormalizer = this.empire.Research > 0.0f ? 1 / (this.empire.Research ) : 1;
            unlockedTech.AddRange(AvailableTechs.Select(techstring => techstring.UID));

            switch (command2)
            {

                case "TECH":
                    {
                        string[] script = modifier.Split(':');
                        for (int i = 1; i < script.Count(); i++)
                        {
                            try
                            {

                                techtype = (TechnologyType)Enum.Parse(typeof(TechnologyType), script[i]);
                            }
                            catch
                            {
                                //techtype = (TechnologyType)Enum.Parse(typeof(TechnologyType), "General");
                                return false;
                            }
                            if (this.empire.data.Traits.Cybernetic > 0 && techtype == (TechnologyType)Enum.Parse(typeof(TechnologyType), "Colonization")) //this.empire.GetBDict()["Biospheres"] &&
                            {
                                //techtype = TechnologyType.Industry;
                                continue;
                            }

                            Technology ResearchTech = null;
                            if (command1 == "CHEAPEST")
                                ResearchTech = AvailableTechs.Where(econ => econ.TechnologyType == techtype).OrderBy(cost => cost.Cost).FirstOrDefault();
                            else if (command1 == "EXPENSIVE")
                                ResearchTech = AvailableTechs.Where(econ => econ.TechnologyType == techtype).OrderByDescending(cost => cost.Cost).FirstOrDefault();

                            //AvailableTechs.Where(econ => econ.TechnologyType == techtype).FirstOrDefault();
                            if (ResearchTech == null)
                                continue;
                            //if (AvailableTechs.Where(econ => econ.TechnologyType == techtype).OrderByDescending(cost => cost.Cost).Count() == 0)
                            //    continue;
                            if (techtype == TechnologyType.Economic)
                            {
                                if (ResearchTech.HullsUnlocked.Count > 0)
                                {
                                    money = this.empire.EstimateIncomeAtTaxRate(.25f);
                                    if (money < 5f)
                                    {
                                        if (command1 == "CHEAPEST")
                                            ResearchTech = AvailableTechs.Where(econ => econ.TechnologyType == techtype && econ != ResearchTech).OrderBy(cost => cost.Cost).FirstOrDefault();
                                        else if (command1 == "EXPENSIVE")
                                            ResearchTech = AvailableTechs.Where(econ => econ.TechnologyType == techtype && econ != ResearchTech).OrderByDescending(cost => cost.Cost).FirstOrDefault();

                                        if (ResearchTech == null)
                                        {
                                            continue;
                                        }
                                    }
                                }
                            }
                            //if (techtype == TechnologyType.ShipDefense ||
                            //    techtype == TechnologyType.ShipGeneral ||
                            //    techtype == TechnologyType.ShipHull ||
                            //    techtype == TechnologyType.ShipWeapons)
                            //{
                            //    if (string.IsNullOrEmpty(this.BestCombatShip))
                            //        return false;
                            //    ship = ResourceManager.ShipsDict[this.BestCombatShip];
                            //    Technology shiptech = AvailableTechs.Where(uid => ship.shipData.techsNeeded.Contains(uid.UID)).OrderBy(techcost => techcost.Cost).FirstOrDefault();
                            //    if (shiptech == null)
                            //    {
                            //        System.Diagnostics.Debug.WriteLine(this.BestCombatShip);
                            //        foreach (string Bestshiptech in ship.shipData.techsNeeded) //.techsNeeded.Where(uid => !ship.shipData.techsNeeded.Contains(uid.UID))
                            //        {
                            //            if (unlockedTech.Contains(Bestshiptech))
                            //                //|| AvailableTechs.Where(uid => uid.UID == Bestshiptech).Count()>0)
                            //                continue;
                            //            System.Diagnostics.Debug.WriteLine("Missing Tech: " + Bestshiptech);
                            //        }
                            //        return false;
                            //    }
                            //    ResearchTech = shiptech;
                            //}
                            string Testresearchtopic = ResearchTech.UID;//AvailableTechs.Where(econ => econ.TechnologyType == techtype).OrderByDescending(cost => cost.Cost).FirstOrDefault().UID;
                            if (string.IsNullOrEmpty(researchtopic))
                                researchtopic = Testresearchtopic;
                            else
                            {
                                int currentCost = (int)(ResearchTech.Cost * CostNormalizer);
                                int previousCost = (int)(ResourceManager.TechTree[researchtopic].Cost * CostNormalizer);

                                if (!string.IsNullOrEmpty(this.BestCombatShip) && (techtype != TechnologyType.ShipHull && //techtype == TechnologyType.ShipHull ||//
                                    ResearchTech.ModulesUnlocked.Count > 0 || ResourceManager.TechTree[researchtopic].ModulesUnlocked.Count > 0))
                                {

                                    Technology PreviousTech = ResourceManager.TechTree[researchtopic];
                                    //Ship
                                        ship = ResourceManager.ShipsDict[this.BestCombatShip];
                                    if (ship.shipData.techsNeeded.Contains(PreviousTech.UID))
                                        previousCost = (int)(previousCost * .5f);
                                    if (ship.shipData.techsNeeded.Contains(ResearchTech.UID))
                                        currentCost = (int)(currentCost * .5f);

                                }

                                if (command1 == "CHEAPEST" && currentCost < previousCost)
                                    researchtopic = Testresearchtopic;
                                else if (command1 == "EXPENSIVE" && currentCost > previousCost)
                                    researchtopic = Testresearchtopic;

                            }

                        }

                        break;
                    }
                case "SHIPTECH":
                    {
                        if (string.IsNullOrEmpty(this.BestCombatShip))
                            return false;
                        ship = ResourceManager.ShipsDict[this.BestCombatShip];
                        Technology shiptech = AvailableTechs.Where(uid => ship.shipData.techsNeeded.Contains(uid.UID)).OrderBy(techcost => techcost.Cost).FirstOrDefault();
                        if (shiptech == null)
                        {
                            System.Diagnostics.Debug.WriteLine(this.BestCombatShip);
                            foreach(string  Bestshiptech in ship.shipData.techsNeeded) //.techsNeeded.Where(uid => !ship.shipData.techsNeeded.Contains(uid.UID))
                            {
                                if ( unlockedTech.Contains(Bestshiptech)  )
                                    //|| AvailableTechs.Where(uid => uid.UID == Bestshiptech).Count()>0)
                                continue;
                                System.Diagnostics.Debug.WriteLine("Missing Tech: " + Bestshiptech);
                            }
                            return false;
                        }
                        researchtopic = shiptech.UID;

                        break;
                    }

                default:
                    {
                        try
                        {

                            techtype = (TechnologyType)Enum.Parse(typeof(TechnologyType), command2);
                            System.Diagnostics.Debug.WriteLine(this.EmpireName + " : " + techtype.ToString());

                        }
                        catch
                        {
                            this.res_strat = GSAI.ResearchStrategy.Random;
                            this.RunResearchPlanner();
                            this.res_strat = GSAI.ResearchStrategy.Scripted;
                            researchtopic = this.empire.ResearchTopic;
                            break;
                        }

                        //This should fix issue 414, but someone else will need to verify it
                        // Allium Sativum
                        Technology ResearchTech = null;
                        ResearchTech = AvailableTechs.OrderByDescending(econ => econ.TechnologyType == techtype).ThenBy(cost => cost.Cost).FirstOrDefault();
                        if (ResearchTech != null)
                        {
                            researchtopic = ResearchTech.UID;
                            break;
                        }
                        //float netresearch =this.empire.GetPlanets().Where(owner => owner.Owner == this.empire).Sum(research => research.NetResearchPerTurn);
                        //netresearch = netresearch == 0 ? 1 : netresearch;
                        //if (ResourceManager.TechTree[researchtopic].Cost / netresearch < 500 )
                        researchtopic = null;
                        break;
                    }
            }
            {
                this.empire.ResearchTopic = researchtopic;
            }
            // else
            {
                // researchtopic = AvailableTechs.OrderBy(cost => cost.Cost).First().UID;
            }

            if (string.IsNullOrEmpty(this.empire.ResearchTopic))
                return false;
            else
            {
                //try
                //{
                //    if (ResourceManager.TechTree[this.empire.ResearchTopic].TechnologyType == TechnologyType.ShipHull)
                //    {
                //        this.BestCombatShip = "";
                //    }
                //}
                //catch(Exception e)
                //{
                //    e.Data.Add("Tech Name(UID)", this.empire.ResearchTopic);

                //}
                System.Diagnostics.Debug.WriteLine(this.EmpireName + " : " + ResourceManager.TechTree[this.empire.ResearchTopic].TechnologyType.ToString());
                return true;
            }
        }
        private void RunResearchPlanner()
        {
            if (string.IsNullOrEmpty(this.empire.ResearchTopic))
            {
                //Added by McShooterz: random tech is less random, selects techs based on priority
                //Check for needs of empire
                        // Ship ship;
                        // int researchneeded = 0;

                        //if( ResourceManager.ShipsDict.TryGetValue(this.BestCombatShip, out ship))
                        //{
                        //    ship.shipData.TechScore / this.empire.Research
                        //}
                bool cybernetic = this.empire.data.Traits.Cybernetic > 0;
                bool atWar = false;
                bool highTaxes = false;
                bool lowResearch = false;
                bool lowincome = false;
                if (this.empire.GetRelations().Where(war => !war.Key.isFaction && ( war.Value.AtWar || war.Value.PreparingForWar)).Count() > 0)
                    atWar = true;
                if (this.empire.data.TaxRate >= .50f )
                    highTaxes = true;
                if (this.empire.GetPlanets().Sum(research => research.NetResearchPerTurn) < this.empire.GetPlanets().Count / 3)
                    lowResearch = true;
                int economics = 10-(int)(this.empire.Money / (this.empire.GrossTaxes +1));
                    //(int)(this.empire.data.TaxRate * 10 + this.empire.Money < this.empire.GrossTaxes?5:0);
                int needsFood =0;
                foreach(Planet hunger in this.empire.GetPlanets())
                {
                    if (cybernetic ? hunger.ProductionHere <1 : hunger.FoodHere <1)
                        needsFood++;

                }

                needsFood = needsFood>0 ? needsFood /this.empire.GetPlanets().Count :0;
                needsFood *= 10;
                //float moneyNeeded = this.empire.canBuildFrigates ? 25 : 0;
                //moneyNeeded = this.empire.canBuildCruisers ? 50 : moneyNeeded;
                //moneyNeeded = this.empire.canBuildCapitals ? 100 : moneyNeeded;
                //float money = this.empire.EstimateIncomeAtTaxRate(.5f) + this.empire.GetTotalShipMaintenance();
                //if (money < moneyNeeded)
                //{
                //    lowincome = true;
                //}
                switch (this.res_strat)
                {
                    case GSAI.ResearchStrategy.Random:
                    {

                        if (true)
                        {
                            Dictionary<string, int> priority = new Dictionary<string, int>();

                            priority.Add("SHIPTECH", HelperFunctions.GetRandomIndex(this.empire.getResStrat().MilitaryPriority + 4+ (atWar ? 6 : 2)));

                            priority.Add("Research", HelperFunctions.GetRandomIndex(this.empire.getResStrat().ResearchPriority +4+ (lowResearch ? 4 : 0)));
                            priority.Add("Colonization", HelperFunctions.GetRandomIndex(this.empire.getResStrat().ExpansionPriority + 4 +(!cybernetic?needsFood:0)));
                            priority.Add("Economic", HelperFunctions.GetRandomIndex(this.empire.getResStrat().ExpansionPriority +4+ (economics) ));
                            priority.Add("Industry", HelperFunctions.GetRandomIndex(this.empire.getResStrat().IndustryPriority + 4+ (cybernetic?needsFood:0)));
                            priority.Add("General", HelperFunctions.GetRandomIndex(4));
                            priority.Add("GroundCombat", HelperFunctions.GetRandomIndex(this.empire.getResStrat().MilitaryPriority +4+ (atWar ? 4 : 0)));

                            string sendToScript = "";
                            int max = 0;
                            foreach (KeyValuePair<string, int> pWeighted in priority.OrderByDescending(pri => pri.Value))
                            {
                                if (max > 3)
                                    break;
                                if (pWeighted.Value < 3 && !string.IsNullOrEmpty(sendToScript))
                                    continue;
                                //if (!string.IsNullOrEmpty(sendToScript))
                                sendToScript += ":";
                                if (pWeighted.Key == "SHIPTECH")
                                {
                                    sendToScript += "ShipWeapons:ShipDefense:ShipGeneral:ShipHull";
                                    max += 4;

                                }
                                else
                                {
                                    sendToScript += pWeighted.Key;
                                    max++;
                                }

                            }
                            if (ScriptedResearch("CHEAPEST", "TECH", "TECH"+sendToScript))
                                return;

                        }

                        //changed by gremlin exclude module tech that we dont have any ships that use it.
                        ConcurrentBag<Technology> AvailableTechs = new ConcurrentBag<Technology>();
                        //foreach (KeyValuePair<string, Ship_Game.Technology> Technology in ResourceManager.TechTree)

                        Parallel.ForEach(ResourceManager.TechTree, Technology =>
                        {
                            TechEntry tech = null;// new TechEntry();
                            bool techexists = this.empire.GetTDict().TryGetValue(Technology.Key, out tech);
                            if (!techexists || tech == null)
                                //continue;
                                return;
                            Technology technology = tech.GetTech();
                            if (tech.Unlocked
                                || !this.empire.HavePreReq(Technology.Key)
                                || (Technology.Value.Secret && !tech.Discovered)
                                || technology.BuildingsUnlocked.Where(winsgame => ResourceManager.BuildingsDict[winsgame.Name].WinsGame == true).Count() > 0
                                || !tech.shipDesignsCanuseThis
                                || (tech.shipDesignsCanuseThis && technology.ModulesUnlocked.Count > 0 && technology.HullsUnlocked.Count == 0
                                && !this.empire.WeCanUseThisNow(tech.GetTech())))
                            {
                                //continue;
                                return;
                            }
                            AvailableTechs.Add(Technology.Value);
                        });
                        if (AvailableTechs.Count == 0)
                            break;
                        foreach(Technology tech in AvailableTechs.OrderBy(tech => tech.Cost))
                        {
                            switch (tech.TechnologyType)
                            {
                                //case TechnologyType.ShipHull:
                                //    {
                                //        //Always research when able
                                //        this.empire.ResearchTopic = tech.UID;
                                //        break;
                                //    }
                                //case TechnologyType.ShipGeneral:
                                //    {
                                //        if (HelperFunctions.GetRandomIndex(4) == 3)
                                //            this.empire.ResearchTopic = tech.UID;
                                //        break;
                                //    }
                                //case TechnologyType.ShipWeapons:
                                //    {
                                //        if(atWar || HelperFunctions.GetRandomIndex(this.empire.getResStrat().MilitaryPriority + 4) > 2)
                                //            this.empire.ResearchTopic = tech.UID;
                                //        break;
                                //    }
                                //case TechnologyType.ShipDefense:
                                //    {
                                //        if (atWar || HelperFunctions.GetRandomIndex(this.empire.getResStrat().MilitaryPriority + 4) > 2)
                                //            this.empire.ResearchTopic = tech.UID;
                                //        break;
                                //    }
                                case TechnologyType.GroundCombat:
                                    {
                                        if (atWar || HelperFunctions.GetRandomIndex(this.empire.getResStrat().MilitaryPriority + 4) > 2)
                                            this.empire.ResearchTopic = tech.UID;
                                        break;
                                    }
                                case TechnologyType.Economic:
                                    {
                                        if (highTaxes || HelperFunctions.GetRandomIndex(this.empire.getResStrat().ExpansionPriority + 4) > 2)
                                            this.empire.ResearchTopic = tech.UID;
                                        break;
                                    }
                                case TechnologyType.Research:
                                    {
                                        if (lowResearch || HelperFunctions.GetRandomIndex(this.empire.getResStrat().ResearchPriority + 4) > 2)
                                            this.empire.ResearchTopic = tech.UID;
                                        break;
                                    }
                                case TechnologyType.Industry:
                                    {
                                        if (HelperFunctions.GetRandomIndex(this.empire.getResStrat().IndustryPriority + 4) > 2)
                                            this.empire.ResearchTopic = tech.UID;
                                        break;
                                    }
                                case TechnologyType.Colonization:
                                    {
                                        if (HelperFunctions.GetRandomIndex(this.empire.getResStrat().ExpansionPriority + 4) > 2)
                                            this.empire.ResearchTopic = tech.UID;
                                        break;
                                    }
                                default:
                                    {
                                        break;
                                    }
                            }
                            if (!string.IsNullOrEmpty(this.empire.ResearchTopic))
                                break;
                        }
                        if (string.IsNullOrEmpty(this.empire.ResearchTopic))
                            this.empire.ResearchTopic = AvailableTechs.OrderBy(tech => tech.Cost).First().UID;
                        break;
                    }
                    case GSAI.ResearchStrategy.Scripted:
                    {
                        int loopcount = 0;
                    Start:
                        if (this.empire.getResStrat() != null && ScriptIndex < this.empire.getResStrat().TechPath.Count &&loopcount < this.empire.getResStrat().TechPath.Count)
                        {

                        string scriptentry = this.empire.getResStrat().TechPath[ScriptIndex].id;
                            string scriptCommand = this.empire.GetTDict().ContainsKey(scriptentry) ?  scriptentry:scriptentry.Split(':')[0];
                            switch (scriptCommand)
                            {

                                case  "SCRIPT":
                                    {

                                        string modifier ="";
                                        string[] script =scriptentry.Split(':');

                                        if(script.Count() >2)
                                        {
                                            modifier = script[2];

                                        }
                                        ScriptIndex++;
                                        if (ScriptedResearch("CHEAPEST",script[1], modifier))
                                            return;
                                        loopcount++;
                                        goto Start;
                                    }
                                case "LOOP":
                                        {
                                            ScriptIndex=int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                            loopcount++;
                                            goto Start;
                                        }
                                case "CHEAPEST":
                                        {
                                        string modifier ="";
                                        string[] script =scriptentry.Split(':');

                                        if(script.Count() ==1)
                                        {
                                            this.res_strat = GSAI.ResearchStrategy.Random;
                                            this.RunResearchPlanner();
                                            this.res_strat = GSAI.ResearchStrategy.Scripted;
                                            ScriptIndex++;
                                            return;

                                        }
                                        string[] modifiers = new string[script.Count()-1];
                                        for(int i=1; i <script.Count();i++)
                                        {
                                            modifiers[i-1] =script[i];
                                        }
                                            modifier =String.Join(":",modifiers);
                                            ScriptIndex++;
                                            if (ScriptedResearch(scriptCommand, script[1], modifier))
                                            return;
                                        loopcount++;
                                        goto Start;

                                        }
                                case "EXPENSIVE":
                                        {
                                            string modifier = "";
                                            string[] script = scriptentry.Split(':');

                                            if (script.Count() == 1)
                                            {
                                                this.res_strat = GSAI.ResearchStrategy.Random;
                                                this.RunResearchPlanner();
                                                this.res_strat = GSAI.ResearchStrategy.Scripted;
                                                ScriptIndex++;
                                                return;

                                            }
                                            string[] modifiers = new string[script.Count() - 1];
                                            for (int i = 1; i < script.Count(); i++)
                                            {
                                                modifiers[i - 1] = script[i];
                                            }
                                            modifier = String.Join(":", modifiers);
                                            ScriptIndex++;
                                            if (ScriptedResearch(scriptCommand,script[1], modifier))
                                                return;
                                            loopcount++;
                                            goto Start;

                                        }
                                case "IFWAR":
                                        {
                                            if (atWar)
                                            {
                                                 ScriptIndex=int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                 loopcount++;
                                            goto Start;

                                            }
                                            ScriptIndex++;

                                            goto Start;

                                        }
                                case "IFHIGHTAX":
                                        {
                                            if (highTaxes)
                                            {
                                                ScriptIndex=int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                            goto Start;
                                            }
                                            ScriptIndex++;

                                            goto  Start;
                                        }
                                case "IFPEACE":
                                        {
                                            if (!atWar)
                                            {
                                                ScriptIndex = int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                                goto Start;
                                            }
                                            ScriptIndex++;

                                            goto Start;
                                        }
                                case "IFCYBERNETIC":
                                        {
                                            if(this.empire.data.Traits.Cybernetic>0 )//&& !this.empire.GetBDict()["Biospheres"])//==true)//this.empire.GetTDict().Where(biosphereTech=> biosphereTech.Value.GetTech().BuildingsUnlocked.Where(biosphere=> ResourceManager.BuildingsDict[biosphere.Name].Name=="Biospheres").Count() >0).Count() >0)
                                            {
                                                ScriptIndex = int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                                goto Start;

                                            }
                                            ScriptIndex++;
                                            goto Start;
                                        }
                                case "IFLOWRESEARCH":
                                        {
                                            if (lowResearch)
                                            {
                                                ScriptIndex = int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                                goto Start;

                                            }
                                            ScriptIndex++;
                                            goto Start;

                                        }
                                case "IFNOTLOWRESEARCH":
                                        {
                                            if (!lowResearch)
                                            {
                                                ScriptIndex = int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                                goto Start;

                                            }
                                            ScriptIndex++;
                                            goto Start;

                                        }
                                case "IFLOWINCOME":
                                        {
                                            if (lowincome)
                                            {
                                                ScriptIndex = int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                                goto Start;

                                            }
                                            ScriptIndex++;
                                            goto Start;

                                        }
                                case "IFNOTLOWINCOME":
                                        {
                                            if (!lowincome)
                                            {
                                                ScriptIndex = int.Parse(this.empire.getResStrat().TechPath[ScriptIndex].id.Split(':')[1]);
                                                loopcount++;
                                                goto Start;

                                            }
                                            ScriptIndex++;
                                            goto Start;

                                        }
                                case "RANDOM":
                                        {
                                            this.res_strat = GSAI.ResearchStrategy.Random;
                                            this.RunResearchPlanner();
                                            this.res_strat = GSAI.ResearchStrategy.Scripted;
                                            ScriptIndex++;
                                            return;
                                        }
                                default:
                                    {

                                        TechEntry defaulttech;
                                        if(this.empire.GetTDict().TryGetValue(scriptentry, out defaulttech))
                                        {
                                            if (defaulttech.Unlocked)

                                            {
                                                ScriptIndex++;
                                                goto Start;
                                            }
                                            if ( !defaulttech.Unlocked && this.empire.HavePreReq(defaulttech.UID))
                                            {
                                                this.empire.ResearchTopic = defaulttech.UID;
                                                ScriptIndex++;
                                                if (!string.IsNullOrEmpty(scriptentry))
                                                    return;
                                            }
                                        }
                                        else
                                        {
                                            System.Diagnostics.Debug.WriteLine("TechNotFound");
                                            System.Diagnostics.Debug.WriteLine(scriptentry);
                                        }

                                        foreach (EconomicResearchStrategy.Tech tech in this.empire.getResStrat().TechPath)
                                        {

                                            if (!this.empire.GetTDict().ContainsKey(tech.id) || this.empire.GetTDict()[tech.id].Unlocked || !this.empire.HavePreReq(tech.id))
                                            {

                                                    continue;
                                            }

                                            int X = GlobalStats.ScriptedTechWithin;
                                            List<TechEntry> unresearched = new List<TechEntry>();
                                            unresearched = this.empire.GetTDict().Values.Where(filter => !filter.Unlocked && filter.shipDesignsCanuseThis && (!filter.GetTech().Secret || !filter.Discovered) && this.empire.HavePreReq(filter.UID) && filter.GetTech().Cost > 0).OrderBy(cost => cost.GetTech().Cost).ToList();
                                            //foreach (TechEntry tech2 in unresearched)//this.empire.GetTDict().Values.Where(filter => !filter.Unlocked && !filter.GetTech().Secret&& filter.Discovered  && filter.GetTech().Cost > 0).OrderBy(cost => cost.GetTech().Cost))
                                            //{
                                            //    X--;
                                            //    if (tech2.UID == tech.id || tech2.GetTech().Cost >= ResourceManager.TechTree[tech.id].Cost * .25F)
                                            //        break;
                                            //    if (X <= 0)
                                            //    {
                                            //        this.res_strat = GSAI.ResearchStrategy.Random;
                                            //        this.RunResearchPlanner();
                                            //        this.res_strat = GSAI.ResearchStrategy.Scripted;
                                            //        ScriptIndex++;
                                            //        return;
                                            //    }

                                            //}

                                                this.empire.ResearchTopic = tech.id;
                                                ScriptIndex++;
                                            if(!string.IsNullOrEmpty(tech.id))
                                                    return;

                                        }
                                        this.res_strat = GSAI.ResearchStrategy.Random;
                                        ScriptIndex++;
                                        return;
                                    }
                            }
                        }
                        if (string.IsNullOrEmpty(this.empire.ResearchTopic))
                        {
                            this.res_strat = GSAI.ResearchStrategy.Random;
                        }
                            return;

                    }
                    default:
                    {
                        return;
                    }
                }
            }
        }