private void DownloadThread(object sender, DoWorkEventArgs e)
        {
            ModDownloadInfo MDI          = (ModDownloadInfo)e.Argument;
            int             RetryCounter = 0;

            while (RetryCounter <= 5 && !threadPermFail)
            {
                try
                {
                    HttpWebRequest hRequest = WebRequest.CreateHttp(MDI.url);
                    hRequest.AddRange(MDI.startPosition, MDI.startPosition + MDI.Length);
                    WebResponse hResp   = hRequest.GetResponse();
                    Stream      nStream = hResp.GetResponseStream();
                    byte[]      b       = new byte[hResp.ContentLength];
                    Debug.WriteLine(MDI.startPosition + " " + MDI.Length + " " + hResp.ContentLength);

                    nStream.Read(b, 0, (int)hResp.ContentLength);
                    if (MDI.Length > hResp.ContentLength)
                    {
                        Array.Resize(ref b, MDI.Length);
                        for (int i = 0; i < MDI.Length - hResp.ContentLength; i++)
                        {
                            b[hResp.ContentLength + i] = 0;
                        }
                    }
                    MemoryStream mstmp = new MemoryStream(b);
                    //nStream.CopyTo(mstmp);
                    DownloadedData.Add(MDI.startPosition, mstmp);
                    //
                    DownloadedBytes += MDI.Length + 1;
                    return;
                }
                catch (Exception ex)
                {
                    RetryCounter++;
                    if (RetryCounter > 5)
                    {
                        threadPermFail = true;
                        //Logger.Error(ex.Message + "\r\nThread: " + MDI.url +", start at " + MDI.startPosition);
                        return;
                    }
                }
            }
        }
        private bool MTDownloader(object data)
        {
            ModToDownload mtd = (ModToDownload)data;

            SetStatusLabelText("Downloading Mod " + mtd.modname);
            DownloadedData  = new Dictionary <int, MemoryStream>();
            DownloadedBytes = 0;
            Logger.Info("Download process for mod " + mtd.modname + " starting, URI: " + mtd.url);
            long mSize = 0;

            HttpWebRequest wRequest = WebRequest.CreateHttp(mtd.url);

            wRequest.Method  = "HEAD";
            wRequest.Timeout = 2000;
            HttpWebResponse wResponse = (HttpWebResponse)wRequest.GetResponse();

            if (wResponse.StatusCode == HttpStatusCode.OK)
            {
                mSize = wResponse.ContentLength;
            }
            else
            {
                Logger.Error("Cannot get length of mod file, exiting. " + mtd.url);
                return(false);
            }
            wResponse.Dispose();
            SetProgressBarMaxValue((int)mSize + 1);
            SetProgressBarValue(0);

            WebClient wc = new WebClient();

            byte[] dt = wc.DownloadData(mtd.url);

            Logger.Info("Size:" + mSize);
            ModThread mds = new ModThread();

            mds.modname = mtd.modname;
            mds.threads = new List <BackgroundWorker>();
            int threadSize       = (int)mSize / 4;
            int endingThreadSize = threadSize + (int)mSize % 4;

            threadPermFail = false;
            for (int i = 0; i < 4; i++)
            {
                ModDownloadInfo mdi = new ModDownloadInfo();
                if (i == 3)
                {
                    mdi.startPosition = i * threadSize;
                    mdi.Length        = endingThreadSize + 1;
                }
                else
                {
                    mdi.startPosition = i * threadSize;
                    mdi.Length        = threadSize;
                }
                mdi.url = mtd.url;
                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += new DoWorkEventHandler(DownloadThread);
                mds.threads.Add(bw);
                mds.threads.Last().RunWorkerAsync(mdi);
            }
            Logger.Info("Download started, thread:1");
            while (true)
            {
                if ((DownloadedBytes % 50) == 0)
                {
                    SetProgressBarValue((int)DownloadedBytes);
                }
                if (DownloadedBytes >= mSize)
                {
                    SetProgressBarValue((int)mSize);
                    CompositeAndWriteFile(mtd.modname);
                    EnableBtns();
                    return(true);
                }
                else
                {
                    if (threadPermFail == true)
                    {
                        MessageBox.Show("Error, a thread failed to download a part of the file.\r\nFile Name:" + mtd.modname);
                        Logger.Error("Download " + mtd.modname + " Failed.");
                        return(false);
                    }
                }
            }
        }