public static string Construct(Lexicon set, ConstructionSequence rule, SemanticData data = null, InfluenceSet influenceSet = null)
        {
            string result = string.Empty;

            bool hasData         = data != null;
            bool hasInfluenceSet = influenceSet != null;

            foreach (var instruction in rule.instructions)
            {
                switch (instruction)
                {
                case ConstructionInstruction.DETERMINER:
                    result += "the ";
                    break;

                case ConstructionInstruction.SEPARATOR:
                    result += " ";
                    break;

                case ConstructionInstruction.NAME_FULL:
                    result += (hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasName) ? influenceSet.Name : set.names.TryGetRandom();
                    break;

                case ConstructionInstruction.NAME_PARTIAL_PREFIX:
                    result += hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasPrefix ? influenceSet.Prefix : set.prefixes.TryGetRandom();
                    break;

                case ConstructionInstruction.NEME_PARTIAL_SUFIX:
                    result += hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasSufix ? influenceSet.Sufix : set.sufixes.TryGetRandom();
                    break;

                case ConstructionInstruction.SUBJECTIVE_ORIGINAL_OR_SYNONYM:
                    result += hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasSynonym ? influenceSet.Synonym : set.synonyms.TryGetRandom();
                    break;

                case ConstructionInstruction.ADJECTIVE:
                    //Consturcts adjective or fallsback to singular noun
                    result += (hasData) ?
                              data.GetAdjective(hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasAdjectiveKey ?
                                                influenceSet.AdjectiveKey : set.adjectiveKeys.TryGetRandom())
                            : set.adjectiveKeys.TryGetRandom();
                    break;

                case ConstructionInstruction.GENETIVE:
                    //Using only singular noun
                    result += (hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasAdjectiveKey) ? influenceSet.AdjectiveKey : set.adjectiveKeys.TryGetRandom();
                    break;

                case ConstructionInstruction.PRESET:
                    result += hasInfluenceSet && Chance.FiftyFifty && influenceSet.HasPreset ? influenceSet.Preset : set.presets.TryGetRandom();
                    break;

                case ConstructionInstruction.PREPOSITION_OF:
                    result += "of ";
                    break;

                case ConstructionInstruction.POSSESSIVE_APOSTROPHE:
                    result += "\'s";
                    break;
                }
            }

            foreach (var concatenationRule in set.concatenationRules)
            {
                result = result.Replace(concatenationRule.replace, concatenationRule.with);
            }

            return(result);
        }
 public string GenerateTitle(SemanticData data = null, InfluenceSet influenceSet = null)
 {
     return(Lexicon.Construct(this, this.titleConstructionRules.TryGetRandom(), data, influenceSet));
 }