/// <summary>
        /// Check If-Match header
        /// </summary>
        /// <param name="objRequest"></param>
        /// <param name="objDownload"></param>
        /// <returns></returns>
        private static bool CheckIfMatch(HttpRequest objRequest, DownloadFile objFile) //Careful ByVal
        {
            // Get Request If-Match Header, * is there was none
            string sRequestHeaderIfMatch = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_IF_MATCH, "*");

            string[] arrEntityIDs;
            bool     bReturn = false;

            if (sRequestHeaderIfMatch.Equals("*"))
            {
                bReturn = true; // No Match
            }
            else
            {
                arrEntityIDs = sRequestHeaderIfMatch.Replace("bytes=", "").Split(",".ToCharArray());
                // Iterate entity IDs to see if there's a match to the current file ID
                for (int iLoop = arrEntityIDs.GetLowerBound(0); iLoop <= arrEntityIDs.GetUpperBound(0); iLoop++)
                {
                    if (arrEntityIDs[iLoop].Trim().Equals(objFile.EntityTag))
                    {
                        bReturn = true;
                    }
                }
            }
            return(bReturn);
        }
        /// <summary>
        /// Check If-Range header
        /// </summary>
        /// <param name="objRequest"></param>
        /// <param name="objDownload"></param>
        /// <returns></returns>
        private static bool CheckIfRange(HttpRequest objRequest, DownloadFile objFile) //Careful ByVal
        {
            // Get Requests If-Range Header value
            string sRequestHeaderIfRange = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_IF_RANGE, objFile.EntityTag);

            // if (the requested file entity matches the current
            // entity uploadId, return True, otherwise return False
            return(sRequestHeaderIfRange.Equals(objFile.EntityTag));
        }
        /// <summary>
        /// Check If-Unmodified-Since header
        /// </summary>
        /// <param name="objRequest"></param>
        /// <param name="objDownload"></param>
        /// <returns></returns>
        private static bool CheckIfUnmodifiedSince(HttpRequest objRequest, DownloadFile objFile)
        {
            string   sSinceDate;
            DateTime dtSinceDate;
            bool     bReturn;

            // Retrieve If-Unmodified-Since Header
            sSinceDate = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_IF_UNMODIFIED_SINCE, String.Empty);
            if (String.IsNullOrEmpty(sSinceDate))
            {
                sSinceDate = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_UNLESS_MODIFIED_SINCE, String.Empty);
            }
            if (String.IsNullOrEmpty(sSinceDate))
            {
                bReturn = true;
            }
            else
            {
                bool     bTry               = DateTime.TryParse(sSinceDate, out dtSinceDate); //dtSinceDate is a local date without millisecs
                DateTime dtSinceDateUTC     = dtSinceDate.ToUniversalTime();
                DateTime dtLastWriteTimeUTC = new DateTime(
                    objFile.LastWriteTimeUTC.Year,
                    objFile.LastWriteTimeUTC.Month,
                    objFile.LastWriteTimeUTC.Day,
                    objFile.LastWriteTimeUTC.Hour,
                    objFile.LastWriteTimeUTC.Minute,
                    objFile.LastWriteTimeUTC.Second,
                    DateTimeKind.Utc);
                if (bTry)
                {
                    bReturn = (dtLastWriteTimeUTC <= dtSinceDateUTC); // True if the file was not modified
                }
                else
                {
                    bReturn = false;
                }
            }
            return(bReturn);
        }
        /// <summary>
        /// Check If-None-Match header
        /// </summary>
        /// <param name="objRequest"></param>
        /// <param name="objResponse"></param>
        /// <param name="objDownload"></param>
        /// <returns></returns>
        private static bool CheckIfNoneMatch(HttpRequest objRequest, HttpResponse objResponse, DownloadFile objFile)  //Careful ByVal
        {
            string sRequestHeaderIfNoneMatch;

            string[] arrEntityIDs;
            bool     bReturn = true;
            string   sReturn = "";

            // Get Request If-None-Match Header value
            sRequestHeaderIfNoneMatch = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_IF_NONE_MATCH, String.Empty);
            if (String.IsNullOrEmpty(sRequestHeaderIfNoneMatch))
            {
                bReturn = true; // Perform request normally
            }
            else if (sRequestHeaderIfNoneMatch.Equals("*"))
            {
                objResponse.StatusCode = 412; // logically invalid request
                bReturn = false;
            }
            else
            {
                arrEntityIDs = sRequestHeaderIfNoneMatch.Replace("bytes=", "").Split(",".ToCharArray());
                // EntIDs were sent - Look for a match to the current one
                for (int iLoop = arrEntityIDs.GetLowerBound(0); iLoop <= arrEntityIDs.GetUpperBound(0); iLoop++)
                {
                    if (arrEntityIDs[iLoop].Trim().Equals(objFile.EntityTag))
                    {
                        sReturn = arrEntityIDs[iLoop];
                        // One of the requested entities matches the current file's tag,
                        objResponse.AppendHeader(HTTP_HEADER_ENTITY_TAG, sReturn);
                        objResponse.StatusCode = 304; // Not Modified
                        bReturn = true;
                    }
                }
            }
            return(bReturn);
        }
        /// <summary>
        /// Check If-Modified-Since header
        /// </summary>
        /// <param name="objRequest"></param>
        /// <param name="objDownload"></param>
        /// <returns></returns>
        private static bool CheckIfModifiedSince(HttpRequest objRequest, DownloadFile objFile) //Careful ByVal
        {
            string   sSinceDate;
            DateTime dtSinceDate;
            bool     bReturn;

            // Retrieve If-Modified-Since Header
            sSinceDate = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_IF_MODIFIED_SINCE, String.Empty);
            if (String.IsNullOrEmpty(sSinceDate))
            {
                bReturn = true; // if (no date was sent - assume we need to re-download the whole file
            }
            else
            {
                bool     bTry               = DateTime.TryParse(sSinceDate, out dtSinceDate); //dtSinceDate is a local date without millisecs
                DateTime dtSinceDateUTC     = dtSinceDate.ToUniversalTime();
                DateTime dtLastWriteTimeUTC = new DateTime(
                    objFile.LastWriteTimeUTC.Year,
                    objFile.LastWriteTimeUTC.Month,
                    objFile.LastWriteTimeUTC.Day,
                    objFile.LastWriteTimeUTC.Hour,
                    objFile.LastWriteTimeUTC.Minute,
                    objFile.LastWriteTimeUTC.Second,
                    DateTimeKind.Utc);
                if (bTry)
                {
                    bReturn = (dtLastWriteTimeUTC > dtSinceDateUTC); // True if the file was actually modified
                }
                else
                {
                    bReturn = false;
                }
            }

            return(bReturn);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="objRequest"></param>
        /// <param name="lBegin"></param>
        /// <param name="lEnd"></param>
        /// <param name="lMax"></param>
        /// <param name="bRangeRequest"></param>
        /// <returns></returns>
        private static bool ParseRequestHeaderRange(HttpRequest objRequest, long lMax, ref long[] lBegin, ref long[] lEnd, ref bool bRangeRequest) //Some ByVal some ByRef
        {
            bool   bValidRangesRet;
            string sSource;

            //int iLoop;
            string[] arrRanges;

            // Retrieve Range Header from Request
            sSource = DownloadHandler.RetrieveHeader(objRequest, HTTP_HEADER_RANGE, String.Empty);
            if (String.IsNullOrEmpty(sSource)) // No Range was requested
            {
                Array.Resize <long>(ref lBegin, 1);
                Array.Resize <long>(ref lEnd, 1);
                lBegin[0]       = 0;
                lEnd[0]         = lMax - 1;
                bValidRangesRet = true;
                bRangeRequest   = false;
            }
            else
            {
                bValidRangesRet = true;
                bRangeRequest   = true;

                // Remove "bytes=" string, and split the rest
                arrRanges = sSource.Replace("bytes=", "").Split(",".ToCharArray());

                Array.Resize <long>(ref lBegin, arrRanges.GetUpperBound(0) + 1);
                Array.Resize <long>(ref lEnd, arrRanges.GetUpperBound(0) + 1);

                // Check each Range request
                for (int iLoop = arrRanges.GetLowerBound(0); iLoop <= arrRanges.GetUpperBound(0); iLoop++)
                {
                    // arrRange(0) is the begin value - arrRange(1) is the end value.
                    string[] arrRange = arrRanges[iLoop].Split("-".ToCharArray());
                    if (String.IsNullOrEmpty(arrRange[1])) // No end was specified
                    {
                        lEnd[iLoop] = lMax - 1;
                    }
                    else
                    {
                        lEnd[iLoop] = long.Parse(arrRange[1], CultureInfo.InvariantCulture);
                    }
                    if (String.IsNullOrEmpty(arrRange[0]))
                    {
                        // Calculate the beginning and end.
                        lBegin[iLoop] = lMax - 1 - lEnd[iLoop];
                        lEnd[iLoop]   = lMax - 1;
                    }
                    else
                    {
                        lBegin[iLoop] = long.Parse(arrRange[0], CultureInfo.InvariantCulture);
                    }
                    // Begin and end must not exceed the total file size
                    if ((lBegin[iLoop] > (lMax - 1)) || (lEnd[iLoop] > (lMax - 1)))
                    {
                        bValidRangesRet = false;
                    }
                    // Begin and end cannot be < 0
                    if ((lBegin[iLoop] < 0) || (lEnd[iLoop] < 0))
                    {
                        bValidRangesRet = false;
                    }
                    // End must be larger or equal to begin value
                    if (lEnd[iLoop] < lBegin[iLoop])
                    {
                        bValidRangesRet = false;
                    }
                }
            }
            return(bValidRangesRet);
        }