public static void AdddLastModified(string url, DateTime lastModified, EntryList tags)
        {
            if (lastModified == DateTime.MinValue)
            {
                return;
            }
            string data = lastModified.ToUniversalTime().Ticks.ToString();

            AddToTags(url, data, tags);
        }
        public static void AddETagToCache( string url, string etag, EntryList tags )
        {
            if( etag == null ) return;
            byte[] utf8 = Encoding.UTF8.GetBytes( url );
            string crc32 = CRC32( utf8 ).ToString();

            for( int i = 0; i < tags.Entries.Count; i++ ) {
                if( !tags.Entries[i].StartsWith( crc32 ) ) continue;
                tags.Entries[i] = crc32 + " " + etag;
                tags.Save(); return;
            }
            tags.AddEntry( crc32 + " " + etag );
        }
        static void AddToTags(string url, string data, EntryList tags)
        {
            string crc32 = CRC32(url);

            for (int i = 0; i < tags.Entries.Count; i++)
            {
                if (!tags.Entries[i].StartsWith(crc32))
                {
                    continue;
                }
                tags.Entries[i] = crc32 + " " + data;
                tags.Save(); return;
            }
            tags.AddEntry(crc32 + " " + data);
        }
        /// <summary> Gets the time the data associated with the url from the cache was last modified,
        /// returning DateTime.MinValue if data for the url was not found in the cache. </summary>
        public static DateTime GetLastModified(string url, EntryList tags)
        {
            string entry = GetFromTags(url, tags);
            long   ticks = 0;

            if (entry != null && long.TryParse(entry, out ticks))
            {
                return(new DateTime(ticks, DateTimeKind.Utc));
            }

            string path = MakePath(url);

            if (!File.Exists(path))
            {
                return(DateTime.MinValue);
            }
            return(File.GetLastWriteTimeUtc(path));
        }
        public static void AddETagToCache(string url, string etag, EntryList tags)
        {
            if (etag == null)
            {
                return;
            }
            byte[] utf8  = Encoding.UTF8.GetBytes(url);
            string crc32 = CRC32(utf8).ToString();

            for (int i = 0; i < tags.Entries.Count; i++)
            {
                if (!tags.Entries[i].StartsWith(crc32))
                {
                    continue;
                }
                tags.Entries[i] = crc32 + " " + etag;
                tags.Save(); return;
            }
            tags.AddEntry(crc32 + " " + etag);
        }
        public static string GetETagFromCache(string url, EntryList tags)
        {
            byte[] utf8  = Encoding.UTF8.GetBytes(url);
            string crc32 = CRC32(utf8).ToString();

            foreach (string entry in tags.Entries)
            {
                if (!entry.StartsWith(crc32))
                {
                    continue;
                }
                string[] parts = entry.Split(trimChars, 2);
                if (parts.Length == 1)
                {
                    continue;
                }
                return(parts[1]);
            }
            return(null);
        }
        static string GetFromTags(string url, EntryList tags)
        {
            string crc32 = CRC32(url);

            for (int i = 0; i < tags.Entries.Count; i++)
            {
                string entry = tags.Entries[i];
                if (!entry.StartsWith(crc32))
                {
                    continue;
                }

                int sepIndex = entry.IndexOf(' ');
                if (sepIndex == -1)
                {
                    continue;
                }
                return(entry.Substring(sepIndex + 1));
            }
            return(null);
        }
 public static string GetETag(string url, EntryList tags)
 {
     return(GetFromTags(url, tags));
 }
        public static string GetETagFromCache( string url, EntryList tags )
        {
            byte[] utf8 = Encoding.UTF8.GetBytes( url );
            string crc32 = CRC32( utf8 ).ToString();

            foreach( string entry in tags.Entries ) {
                if( !entry.StartsWith( crc32 ) ) continue;
                string[] parts = entry.Split( trimChars, 2 );
                if( parts.Length == 1 ) continue;
                return parts[1];
            }
            return null;
        }