private static UriTemplatePart[] ParseTemplate(string template) { List <UriTemplatePart> parts = new List <UriTemplatePart>(); int previousEnd = 0; foreach (Match match in ExpressionExpression.Matches(template)) { if (match.Index > previousEnd) { parts.Add(new UriTemplatePartLiteral(template.Substring(previousEnd, match.Index - previousEnd))); } UriTemplatePartType type = UriTemplatePartType.SimpleStringExpansion; Group op = match.Groups["Operator"]; if (op.Success && op.Length > 0) { switch (op.Value) { case "+": type = UriTemplatePartType.ReservedStringExpansion; break; case "#": type = UriTemplatePartType.FragmentExpansion; break; case ".": type = UriTemplatePartType.LabelExpansion; break; case "/": type = UriTemplatePartType.PathSegments; break; case ";": type = UriTemplatePartType.PathParameters; break; case "?": type = UriTemplatePartType.Query; break; case "&": type = UriTemplatePartType.QueryContinuation; break; case "=": case ",": case "!": case "@": case "|": throw new NotSupportedException(string.Format("Operator is reserved for future expansion: {0}", op.Value)); default: throw new InvalidOperationException("Unreachable"); } } Group variableList = match.Groups["VariableList"]; VariableReference[] variables; if (variableList.Success) { string[] specs = variableList.Value.Split(','); variables = new VariableReference[specs.Length]; for (int i = 0; i < specs.Length; i++) { variables[i] = VariableReference.Parse(specs[i]); } } else { variables = new VariableReference[0]; } UriTemplatePart part; switch (type) { case UriTemplatePartType.SimpleStringExpansion: part = new UriTemplatePartSimpleExpansion(variables, true); break; case UriTemplatePartType.ReservedStringExpansion: part = new UriTemplatePartSimpleExpansion(variables, false); break; case UriTemplatePartType.FragmentExpansion: part = new UriTemplatePartFragmentExpansion(variables); break; case UriTemplatePartType.LabelExpansion: part = new UriTemplatePartLabelExpansion(variables); break; case UriTemplatePartType.PathSegments: part = new UriTemplatePartPathSegmentExpansion(variables); break; case UriTemplatePartType.PathParameters: part = new UriTemplatePartPathParametersExpansion(variables); break; case UriTemplatePartType.Query: part = new UriTemplatePartQueryExpansion(variables, false); break; case UriTemplatePartType.QueryContinuation: part = new UriTemplatePartQueryExpansion(variables, true); break; case UriTemplatePartType.Literal: default: throw new InvalidOperationException("Unreachable"); } parts.Add(part); previousEnd = match.Index + match.Length; } if (previousEnd < template.Length) { parts.Add(new UriTemplatePartLiteral(template.Substring(previousEnd))); } return(parts.ToArray()); }