private static void GetResponseCallback(IAsyncResult ar)
    {
        HttpClientHelper dlf = (HttpClientHelper)ar.AsyncState;

        try
        {
            dlf.m_reponse = (HttpWebResponse)dlf.m_request.EndGetResponse(ar);

            HttpStatusCode code = dlf.m_reponse.StatusCode;
            if (code == HttpStatusCode.Found ||
                code == HttpStatusCode.Redirect ||
                code == HttpStatusCode.Moved ||
                code == HttpStatusCode.MovedPermanently)
            {
                dlf.m_redirectURL = dlf.m_reponse.Headers["Location"];
                dlf.Close(HTTP_OP_RET.failed, (int)code, dlf.m_reponse.StatusDescription);
                return;
            }


            dlf.m_totalSize      = dlf.m_reponse.ContentLength;
            dlf.m_responseStream = dlf.m_reponse.GetResponseStream();

            dlf.m_fileBuffStream = new MemoryStream();
            dlf.m_opStep         = HTTP_OP_STEP.downloading;

            IAsyncResult iarRead = dlf.m_responseStream.BeginRead(dlf.m_buffer, 0, BUFFER_SIZE, new AsyncCallback(ReadCallback), dlf);
            ThreadPool.RegisterWaitForSingleObject(iarRead.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), dlf, TIMEOUT, true);
        }
        catch (WebException e)
        {
            HttpStatusCode code = HttpStatusCode.BadRequest;

            if (e.Status == WebExceptionStatus.Timeout)
            {
                code = HttpStatusCode.RequestTimeout;
            }
            else if (e.Status == WebExceptionStatus.ConnectFailure)
            {
                code = HttpStatusCode.InternalServerError;
            }
            else
            {
                HttpWebResponse response = e.Response as HttpWebResponse;
                code = response.StatusCode;
            }

            dlf.Close(HTTP_OP_RET.failed, (int)code, e.ToString());
        }
        catch (Exception e)
        {
            dlf.Close(HTTP_OP_RET.failed, -1, e.ToString());
        }
    }
    private static void TimeoutCallback(object state, bool timeOut)
    {
        HttpClientHelper dlf = (HttpClientHelper)state;

        if (timeOut)
        {
            dlf.Close(HTTP_OP_RET.time_out, (int)HttpStatusCode.RequestTimeout, "");
        }
    }
    private static void ReadCallback(IAsyncResult asyncResult)
    {
        HttpClientHelper dlf = (HttpClientHelper)asyncResult.AsyncState;

        if (dlf.m_responseStream == null)
        {
            return;
        }

        try
        {
            int read = dlf.m_responseStream.EndRead(asyncResult);
            if (read > 0)
            {
                dlf.m_fileBuffStream.Write(dlf.m_buffer, 0, read);
                dlf.m_downloadSize += read;

                if (dlf.m_downloadSize < dlf.m_totalSize)
                {
                    IAsyncResult iarRead = dlf.m_responseStream.BeginRead(dlf.m_buffer, 0, BUFFER_SIZE, new AsyncCallback(ReadCallback), dlf);
                    ThreadPool.RegisterWaitForSingleObject(iarRead.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), dlf, TIMEOUT, true);
                }
                else
                {
                    dlf.Close(HTTP_OP_RET.succ, (int)HttpStatusCode.OK, "");
                }
            }
            else
            {
                //TODO: kevin. will it raise an excpetion ?
                //dlf.Close(HTTP_OP_RET.failed, -1, "ReadCallback");
            }
        }
        catch (WebException e)
        {
            HttpWebResponse response = e.Response as HttpWebResponse;
            dlf.Close(HTTP_OP_RET.failed, (int)response.StatusCode, e.ToString());
        }
        catch (Exception e)
        {
            dlf.Close(HTTP_OP_RET.failed, -1, e.ToString());
        }
    }