private static bool TrySetCacheControlValues(
            CacheControlHeaderValue cc,
            List <NameValueHeaderValue> nameValueList)
        {
            for (var i = 0; i < nameValueList.Count; i++)
            {
                var nameValue = nameValueList[i];
                var name      = nameValue.Name;
                var success   = true;

                switch (name.Length)
                {
                case 6:
                    if (StringSegment.Equals(PublicString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTokenOnlyValue(nameValue, ref cc._public);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 7:
                    if (StringSegment.Equals(MaxAgeString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTimeSpan(nameValue, ref cc._maxAge);
                    }
                    else if (StringSegment.Equals(PrivateString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetOptionalTokenList(nameValue, ref cc._private, ref cc._privateHeaders);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 8:
                    if (StringSegment.Equals(NoCacheString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetOptionalTokenList(nameValue, ref cc._noCache, ref cc._noCacheHeaders);
                    }
                    else if (StringSegment.Equals(NoStoreString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTokenOnlyValue(nameValue, ref cc._noStore);
                    }
                    else if (StringSegment.Equals(SharedMaxAgeString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTimeSpan(nameValue, ref cc._sharedMaxAge);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 9:
                    if (StringSegment.Equals(MaxStaleString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = ((nameValue.Value == null) || TrySetTimeSpan(nameValue, ref cc._maxStaleLimit));
                        if (success)
                        {
                            cc._maxStale = true;
                        }
                    }
                    else if (StringSegment.Equals(MinFreshString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTimeSpan(nameValue, ref cc._minFresh);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 12:
                    if (StringSegment.Equals(NoTransformString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTokenOnlyValue(nameValue, ref cc._noTransform);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 14:
                    if (StringSegment.Equals(OnlyIfCachedString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTokenOnlyValue(nameValue, ref cc._onlyIfCached);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 15:
                    if (StringSegment.Equals(MustRevalidateString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTokenOnlyValue(nameValue, ref cc._mustRevalidate);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case 16:
                    if (StringSegment.Equals(ProxyRevalidateString, name, StringComparison.OrdinalIgnoreCase))
                    {
                        success = TrySetTokenOnlyValue(nameValue, ref cc._proxyRevalidate);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                default:
                    cc.Extensions.Add(nameValue);     // success is always true
                    break;
                }

                if (!success)
                {
                    return(false);
                }
            }

            return(true);
        }
        private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue parsedValue)
        {
            Contract.Requires(startIndex >= 0);

            parsedValue = null;

            if (StringSegment.IsNullOrEmpty(input) || (startIndex >= input.Length))
            {
                return(0);
            }

            // Cache-Control header consists of a list of name/value pairs, where the value is optional. So use an
            // instance of NameValueHeaderParser to parse the string.
            var current = startIndex;
            NameValueHeaderValue nameValue = null;
            var nameValueList = new List <NameValueHeaderValue>();

            while (current < input.Length)
            {
                if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out nameValue))
                {
                    return(0);
                }

                nameValueList.Add(nameValue);
            }

            // If we get here, we were able to successfully parse the string as list of name/value pairs. Now analyze
            // the name/value pairs.

            // Cache-Control is a header supporting lists of values. However, expose the header as an instance of
            // CacheControlHeaderValue.
            var result = new CacheControlHeaderValue();

            if (!TrySetCacheControlValues(result, nameValueList))
            {
                return(0);
            }

            parsedValue = result;

            // If we get here we successfully parsed the whole string.
            return(input.Length - startIndex);
        }