public static UriTemplatePathSegment CreateFromUriTemplate(string segment, UriTemplate template)
        {
            // Identifying the type of segment - Literal|Compound|Variable
            switch (UriTemplateHelpers.IdentifyPartType(segment))
            {
            case UriTemplatePartType.Literal:
                return(UriTemplateLiteralPathSegment.CreateFromUriTemplate(segment, template));

            case UriTemplatePartType.Compound:
                return(UriTemplateCompoundPathSegment.CreateFromUriTemplate(segment, template));

            case UriTemplatePartType.Variable:
                if (segment.EndsWith("/", StringComparison.Ordinal))
                {
                    var varName = template.AddPathVariable(UriTemplatePartType.Variable,
                                                           segment.Substring(1, segment.Length - 3));
                    return(new UriTemplateVariablePathSegment(segment, true, varName));
                }
                else
                {
                    var varName = template.AddPathVariable(UriTemplatePartType.Variable,
                                                           segment.Substring(1, segment.Length - 2));
                    return(new UriTemplateVariablePathSegment(segment, false, varName));
                }

            default:
                throw new Exception("Invalid value from IdentifyStringNature");
            }
        }
        public static new UriTemplateCompoundPathSegment CreateFromUriTemplate(string segment, UriTemplate template)
        {
            var origSegment   = segment;
            var endsWithSlash = segment.EndsWith("/", StringComparison.Ordinal);

            if (endsWithSlash)
            {
                segment = segment.Remove(segment.Length - 1);
            }

            var nextVarStart = segment.IndexOf("{", StringComparison.Ordinal);

            Ensure.Nonnegative(nextVarStart,
                               "The method is only called after identifying a '{' character in the segment");
            var firstLiteral = ((nextVarStart > 0) ? segment.Substring(0, nextVarStart) : string.Empty);

            if (firstLiteral.IndexOf(UriTemplate.WildcardPath, StringComparison.Ordinal) != -1)
            {
                throw new FormatException($"UTInvalidWildcardInVariableOrLiteral {template.OriginalTemplate} {UriTemplate.WildcardPath}");
            }
            var result = new UriTemplateCompoundPathSegment(origSegment, endsWithSlash,
                                                            ((firstLiteral != string.Empty) ? Uri.UnescapeDataString(firstLiteral) : string.Empty));

            do
            {
                var nextVarEnd = segment.IndexOf("}", nextVarStart + 1, StringComparison.Ordinal);
                if (nextVarEnd < nextVarStart + 2)
                {
                    throw new FormatException($"UTInvalidFormatSegmentOrQueryPart {segment}");
                }
                bool hasDefault;
                var  varName = template.AddPathVariable(UriTemplatePartType.Compound,
                                                        segment.Substring(nextVarStart + 1, nextVarEnd - nextVarStart - 1), out hasDefault);
                if (hasDefault)
                {
                    throw new InvalidOperationException(
                              $"UTDefaultValueToCompoundSegmentVar template:{template},origSegment:{origSegment},varName:{varName}");
                }
                nextVarStart = segment.IndexOf("{", nextVarEnd + 1, StringComparison.Ordinal);
                string literal;
                if (nextVarStart > 0)
                {
                    if (nextVarStart == nextVarEnd + 1)
                    {
                        throw new ArgumentException($"UTDoesNotSupportAdjacentVarsInCompoundSegment template:{template},segment:{segment}");
                    }
                    literal = segment.Substring(nextVarEnd + 1, nextVarStart - nextVarEnd - 1);
                }
                else if (nextVarEnd + 1 < segment.Length)
                {
                    literal = segment.Substring(nextVarEnd + 1);
                }
                else
                {
                    literal = string.Empty;
                }
                if (literal.IndexOf(UriTemplate.WildcardPath, StringComparison.Ordinal) != -1)
                {
                    throw new FormatException($"UTInvalidWildcardInVariableOrLiteral {template.OriginalTemplate} {UriTemplate.WildcardPath}");
                }
                if (literal.IndexOf('}') != -1)
                {
                    throw new FormatException($"UTInvalidFormatSegmentOrQueryPart {segment}");
                }
                result._varLitPairs.Add(new VarAndLitPair(varName, ((literal == string.Empty) ? string.Empty : Uri.UnescapeDataString(literal))));
            } while (nextVarStart > 0);

            if (string.IsNullOrEmpty(result._firstLiteral))
            {
                if (string.IsNullOrEmpty(result._varLitPairs[result._varLitPairs.Count - 1].Literal))
                {
                    result._csClass = CompoundSegmentClass.HasNoPrefixNorSuffix;
                }
                else
                {
                    result._csClass = CompoundSegmentClass.HasOnlySuffix;
                }
            }
            else
            {
                if (string.IsNullOrEmpty(result._varLitPairs[result._varLitPairs.Count - 1].Literal))
                {
                    result._csClass = CompoundSegmentClass.HasOnlyPrefix;
                }
                else
                {
                    result._csClass = CompoundSegmentClass.HasPrefixAndSuffix;
                }
            }

            return(result);
        }