using System;
using System.Text;
using System.Collections.Generic;
 
public class Test
{
    public static string Replace(string input, ref int pos, IDictionary<string,string> vars, bool stopOnClose = false) {
        var res = new StringBuilder();
        while (pos != input.Length) {
            switch (input[pos]) {
                case '\\':
                    pos++;
                    if (pos != input.Length) {
                        res.Append(input[pos++]);
                    }
                    break;
                case ')':
                    if (stopOnClose) {
                        return res.ToString();
                    }
                    res.Append(')');
                    pos++;
                    break;
                case '$':
                    pos++;
                    if (pos != input.Length && input[pos] == '(') {
                        pos++;
                        var name = Replace(input, ref pos, vars, true);
                        string replacement;
                        if (vars.TryGetValue(name, out replacement)) {
                            res.Append(replacement);
                        } else {
                            res.Append("<UNKNOWN:");
                            res.Append(name);
                            res.Append(">");
                        }
                        pos++;
                    } else {
                        res.Append('$');
                    }
                    break;
                default:
                    res.Append(input[pos++]);
                    break;
            }
        }
        return res.ToString();
    }
    public static void Main() {
        const string input = "Here is a test string contain $(variableA) and $(variableB$(variableC))";
        var vars = new Dictionary<string, string> {
            {"variableA", "A"}, {"variableB", "B"}, {"variableC", "C"}, {"variableBC", "Y"}
        };
        int pos = 0;
        Console.WriteLine(Replace(input, ref pos, vars));
    }
}
				dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGV4dDsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CgpwdWJsaWMgY2xhc3MgVGVzdAp7CiAgICBwdWJsaWMgc3RhdGljIHN0cmluZyBSZXBsYWNlKHN0cmluZyBpbnB1dCwgcmVmIGludCBwb3MsIElEaWN0aW9uYXJ5PHN0cmluZyxzdHJpbmc+IHZhcnMsIGJvb2wgc3RvcE9uQ2xvc2UgPSBmYWxzZSkgewogICAgICAgIHZhciByZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIHdoaWxlIChwb3MgIT0gaW5wdXQuTGVuZ3RoKSB7CiAgICAgICAgICAgIHN3aXRjaCAoaW5wdXRbcG9zXSkgewogICAgICAgICAgICAgICAgY2FzZSAnXFwnOgogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgIGlmIChwb3MgIT0gaW5wdXQuTGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5BcHBlbmQoaW5wdXRbcG9zKytdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICcpJzoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RvcE9uQ2xvc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXMuQXBwZW5kKCcpJyk7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICckJzoKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICBpZiAocG9zICE9IGlucHV0Lkxlbmd0aCAmJiBpbnB1dFtwb3NdID09ICcoJykgewogICAgICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWUgPSBSZXBsYWNlKGlucHV0LCByZWYgcG9zLCB2YXJzLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHJlcGxhY2VtZW50OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFycy5UcnlHZXRWYWx1ZShuYW1lLCBvdXQgcmVwbGFjZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMuQXBwZW5kKHJlcGxhY2VtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5BcHBlbmQoIjxVTktOT1dOOiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZChuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5BcHBlbmQoIj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXMuQXBwZW5kKCckJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXMuQXBwZW5kKGlucHV0W3BvcysrXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcy5Ub1N0cmluZygpOwogICAgfQogICAgcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKSB7CiAgICAgICAgY29uc3Qgc3RyaW5nIGlucHV0ID0gIkhlcmUgaXMgYSB0ZXN0IHN0cmluZyBjb250YWluICQodmFyaWFibGVBKSBhbmQgJCh2YXJpYWJsZUIkKHZhcmlhYmxlQykpIjsKICAgICAgICB2YXIgdmFycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPiB7CiAgICAgICAgICAgIHsidmFyaWFibGVBIiwgIkEifSwgeyJ2YXJpYWJsZUIiLCAiQiJ9LCB7InZhcmlhYmxlQyIsICJDIn0sIHsidmFyaWFibGVCQyIsICJZIn0KICAgICAgICB9OwogICAgICAgIGludCBwb3MgPSAwOwogICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKFJlcGxhY2UoaW5wdXQsIHJlZiBwb3MsIHZhcnMpKTsKICAgIH0KfQ==