}//ReplaceOnInput(string text, List<InputReplacement> replacements)

        public static string ReplaceSynonyms(string input, Dictionary <string, Synonym> synonyms)
        {
            int start = input.IndexOf("(");
            int end;

            while (start != -1)
            {
                end = TextToolbox.FindNextMatchingChar(input, start);
                if (end != -1)
                {
                    string synonymName = input.Substring(start + 1, end - start - 1).Trim().ToLower();
                    if (synonyms.ContainsKey(synonymName))
                    {
                        input = input.Substring(0, start + 1) + ((Synonym)synonyms[synonymName]).GetPhrases() + input.Substring(end);
                    }
                    else
                    {
                        input = input.Substring(0, start) + "(" + synonymName + ")" + input.Substring(end + 1);
                    }
                    start = input.IndexOf("(", start + 1);
                }
                else                //there's an error with this input, it won't compile
                {
                    //TODO: log an error somewhere?
                    return("");
                }
            }
            return(input);
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)

        public static string ReplaceOutputSynonyms(string text, Dictionary <string, Synonym> synonyms)
        {
            int start = text.IndexOf("(");
            int end;

            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string synonymName = text.Substring(start + 1, end - start - 1).Trim().ToLower();
                        if (synonyms.ContainsKey(synonymName) && !TextToolbox.IsInCommand(text, start, end - start))
                        {
                            Synonym syn = ((Synonym)synonyms[synonymName]);
                            if (syn.Phrases.Count > 0)
                            {
                                Random rand = new Random();
                                int    pick = rand.Next(syn.Phrases.Count);
                                if (end == text.Length - 1)                               //the end is the end
                                {
                                    text = text.Substring(0, start) + ((Phrase)syn.Phrases[pick]).Text;
                                }
                                else
                                {
                                    text = text.Substring(0, start) + ((Phrase)syn.Phrases[pick]).Text + text.Substring(end + 1);
                                }
                            }
                            else
                            {
                                text = text.Substring(0, start + 1) + synonymName + text.Substring(end);
                            }
                        }
                        start = text.IndexOf("(", start + 1);
                    }
                    else
                    {
                        //TODO: log an error somewhere?
                        return(text);
                    }
                }
                else                 //it's escaped \(..
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf("(", start);
                    }
                }
            }            //while
            return(text);
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)

        public static string ReplaceVars(string text, Hashtable vars)
        {
            int start = text.IndexOf("[");
            int end;

            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string varName         = TextToolbox.ReplaceVars(text.Substring(start + 1, end - start - 1), vars);
                        string varDefaultValue = "";
                        if (varName.IndexOf(':') != -1)
                        {
                            varDefaultValue = varName.Substring(varName.IndexOf(':') + 1).Trim();
                            varName         = varName.Substring(0, varName.IndexOf(':')).Trim();
                        }
                        varName = varName.Replace(" ", "_");
                        string varValue = (string)vars[varName.ToLower()];
                        if (varValue == null)
                        {
                            varValue = varDefaultValue;
                        }

                        if (end == text.Length - 1)                       //var runs to the end
                        {
                            text  = text.Substring(0, start) + varValue;
                            start = -1;
                        }
                        else
                        {
                            text  = text.Substring(0, start) + varValue + text.Substring(end + 1);
                            start = text.IndexOf("[", start + varValue.Length);
                        }
                    }
                    else                    //there's an error with this input, it won't compile
                    {
                        //TODO: log an error somewhere?
                        return("");
                    }
                }
                else                // [ is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf("[", start);
                    }
                }
            }            //while we have more [vars]

            string embCmd = "<mem.get ";

            start = text.IndexOf(embCmd);
            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string name = text.Substring(start + embCmd.Length, end - start - embCmd.Length);
                        string left = "";
                        if (start > 0)
                        {
                            left = text.Substring(0, start);
                        }
                        string right = "";
                        if (end + 1 != text.Length)
                        {
                            right = text.Substring(end + 1);
                        }
                        text = left + vars[name.ToLower()] + right;
                    }
                    start = text.IndexOf(embCmd);
                }
                else                // < is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf(embCmd, start);
                    }
                }
            }            //while we have more <mem.get name>s

            embCmd = "<mem.set ";
            start  = text.IndexOf(embCmd);
            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string   nameValue = text.Substring(start + embCmd.Length, end - start - embCmd.Length);
                        string   left      = "";
                        string   right     = "";
                        string[] cmdArgs   = TextToolbox.splitOnFirstUnquotedSpace(nameValue);

                        if (cmdArgs.Length > 1)
                        {
                            string name = cmdArgs[0];
                            //remove quotes if they are there
                            if (name.Length > 1 && name[0] == '"')
                            {
                                name = name.Substring(1);
                            }
                            if (name.Length > 2 && name[name.Length - 1] == '"')
                            {
                                name = name.Substring(0, name.Length - 1);
                            }
                            string val = cmdArgs[1];
                            vars[name.ToLower()] = val;
                        }

                        if (start > 0)
                        {
                            left = text.Substring(0, start);
                        }
                        if (end + 1 != text.Length)
                        {
                            right = text.Substring(end + 1);
                        }
                        text = left + right;
                    }
                    start = text.IndexOf(embCmd);
                }
                else                // < is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf(embCmd, start);
                    }
                }
            }            //while we have more <mem.set name>s

            embCmd = "<mem.del ";
            start  = text.IndexOf(embCmd);
            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string name = text.Substring(start + embCmd.Length, end - start - embCmd.Length);
                        vars.Remove(name.Trim().ToLower());
                        string left  = "";
                        string right = "";
                        if (start > 0)
                        {
                            left = text.Substring(0, start);
                        }
                        if (end + 1 != text.Length)
                        {
                            right = text.Substring(end + 1);
                        }
                        text = left + right;
                    }
                    start = text.IndexOf(embCmd);
                }
                else                // < is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf(embCmd, start);
                    }
                }
            }    //while we have more <mem.set name>s
            return(text);
        }        //ReplaceVars(string text, Hashtable vars)