private static string SubstitutePlaceholders(string template, Arr <SimParameter> parameters) { var nSubstitutions = parameters.Count; var parts = template.Split(new string[] { "${" }, StringSplitOptions.None); RequireEqual(parts.Length, nSubstitutions + 1, "Incompatible parameter set and template: non-equal substitutions"); if (0 == nSubstitutions) { return(template); } var sb = new StringBuilder(parts[0]); for (var i = 1; i < parts.Length; ++i) { var part = parts[i]; var posRBrace = part.IndexOf('}'); RequireTrue(posRBrace.IsFound(), "No closing } in section: " + part); var name = part.Substring(0, posRBrace).Trim(); var parameter = parameters .FindParameter(name) .AssertSome($"Template specifies unknown parameter: {name}"); sb.Append(parameter.GetRValue()); sb.Append(part[(posRBrace + 1)..]);