private List <QueryableProperty> CalculatePossibleQueryableProperties(List <QuerySet> querySets, int wiresAvailableInQuery, bool compoundQueriesAllowed)
        {
            List <QueryableProperty> list = new List <QueryableProperty>();

            foreach (QuerySet querySet in querySets)
            {
                foreach (QueryableProperty queryableProperty in querySet.QueryableProperties)
                {
                    if (!queryableProperty.CompoundQueryOnly || compoundQueriesAllowed)
                    {
                        QueryableWireProperty queryableWireProperty = queryableProperty as QueryableWireProperty;
                        if (queryableWireProperty == null || queryableWireProperty.WiresInvolvedInQuery <= wiresAvailableInQuery)
                        {
                            list.Add(queryableProperty);
                        }
                    }
                }
            }
            List <QueryableProperty> list2 = list.ToList <QueryableProperty>();

            foreach (QueryableProperty key in list2)
            {
                if (!queryPropertyWeights.ContainsKey(key))
                {
                    queryPropertyWeights.Add(key, 1f);
                }
            }
            return(list2);
        }
        protected override AbstractRuleSet CreateRules(bool useDefault)
        {
            WireRuleSet     wireRuleSet         = new WireRuleSet();
            QuerySet        serialNumberQueries = QuerySet.GetSerialNumberQueries();
            QuerySet        wireQueries         = QuerySet.GetWireQueries();
            QuerySet        portQueries         = QueryablePorts.GetPortQueries();
            List <QuerySet> list = new List <QuerySet>();

            for (int i = WireSetComponent.MIN_WIRES; i <= WireSetComponent.MAX_WIRES; i++)
            {
                List <Rule> list2 = new List <Rule>();
                list.Clear();
                list.Add(serialNumberQueries);
                list.Add(wireQueries);
                if (RuleManager.SeedIsModded)
                {
                    list.Add(portQueries);
                }
                queryPropertyWeights.Clear();
                solutionWeights.Clear();
                int numRules = GetNumRules();
                for (int j = 0; j < numRules; j++)
                {
                    List <WireColor> listOfWireColors = RuleUtil.GetListOfWireColors();
                    Rule             rule             = new Rule();
                    int numQueriesForRule             = GetNumQueriesForRule();
                    List <WireColor> list3            = new List <WireColor>();
                    int num = i - 1;
                    for (int k = 0; k < numQueriesForRule; k++)
                    {
                        bool compoundQueriesAllowed = k > 0;
                        List <QueryableProperty> possibleQueryableProperties = CalculatePossibleQueryableProperties(list, num, compoundQueriesAllowed);
                        QueryableProperty        queryableProperty           = SelectQueryableProperty(possibleQueryableProperties);
                        Query query = new Query();
                        query.Property = queryableProperty;
                        if (queryableProperty is QueryableWireProperty)
                        {
                            QueryableWireProperty queryableWireProperty = (QueryableWireProperty)queryableProperty;
                            num -= queryableWireProperty.WiresInvolvedInQuery;
                            if (queryableWireProperty.UsesColor)
                            {
                                WireColor wireColor = listOfWireColors[rand.Next(0, listOfWireColors.Count)];
                                listOfWireColors.Remove(wireColor);
                                query.Args.Add("color", wireColor);
                                if (queryableWireProperty.ColorAvailableForSolution)
                                {
                                    list3.Add(wireColor);
                                }
                            }
                        }
                        rule.Queries.Add(query);
                    }
                    List <Solution> possibleSolutions = CalculatePossibleSolutions(i, rule);
                    Solution        solution          = SelectSolution(possibleSolutions);
                    rule.Solution = solution;
                    if (list3.Count > 0)
                    {
                        rule.SolutionArgs.Add("color", list3[rand.Next(0, list3.Count)]);
                    }
                    if (RuleManager.SeedIsVanilla || IsWireQueryValid(rule))
                    {
                        list2.Add(rule);
                    }
                    else
                    {
                        j--;    //Previous rule was never valid.
                    }
                }
                list2 = list2.OrderByDescending(x => x.Queries.Count).ToList();
                Rule  otherwiseRule  = new Rule();
                Query otherwiseQuery = new Query {
                    Property = QueryableProperty.Otherwise
                };
                otherwiseRule.Queries.Add(otherwiseQuery);
                List <Solution> list4 = CalculatePossibleSolutions(i, otherwiseRule);
                if (RuleManager.SeedIsModded)
                {
                    list4.Remove(list2.Last().Solution);    //Enforce no redundant rules.
                }
                otherwiseRule.Solution = list4[rand.Next(0, list4.Count)];
                list2.Add(otherwiseRule);
                wireRuleSet.RulesDictionary[i] = list2;
            }
            return(wireRuleSet);
        }