private void btnStart_Click(object sender, EventArgs e)
        {
            // Checking pre-condition
            if (this.cbSysMenu.SelectedIndex == -1 || String.IsNullOrEmpty(this.tbSaveAs.Text))
            {
                MessageBox.Show("Please, select a System Menu and path to extract !", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Checking serial number
            if (!String.IsNullOrEmpty(this.tbSerialNumber.Text) && !SettingTxt.isValidSerialNumber(this.tbSerialNumber.Text.Replace(" ", "")))
            {
                MessageBox.Show("Invalid Wii Serial Number !", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Init and start thread
            this.LockUnlockForm();
            this.rtbOutput.Clear();
            this.ssBuildNand.Text          = "";
            this.pbProgressBuildNand.Value = 0;
            this.pbGlobal.Value            = 0;
            sysMenu         = this.cbSysMenu.SelectedItem.ToString();
            wiiSerialNumber = this.tbSerialNumber.Text.Replace(" ", "");
            nandPath        = this.tbSaveAs.Text;
            fullNand        = this.rbFullNand.Checked;

            this.nusWorkerThread = new Thread(new ThreadStart(BuildNand));
            this.nusWorkerThread.Start();
        }
        private void BuildNand()
        {
            // Deletage to fire current action description
            objectInvoker delegateMethodeLabelLog       = new objectInvoker(this.updateLabelLog);
            objectInvoker delegateMethodeLog            = new objectInvoker(this.updateLog);
            objectInvoker delegateMethodeGlobalProgress = new objectInvoker(this.initGlobalProgress);

            // IOS list
            List <string[]> titleList = new List <string[]>();

            // Temp directory
            string tmpPath = Path.GetTempPath();

            // System Menu and his IOS.
            switch (this.sysMenu)
            {
            case "4.2J":
                // System Menu
                titleList.Add(new string[2] {
                    "0000000100000002", "480"
                });
                // IOS70
                titleList.Add(new string[2] {
                    "0000000100000046", "6944"
                });
                break;

            case "4.2U":
                // System Menu
                titleList.Add(new string[2] {
                    "0000000100000002", "481"
                });
                // IOS70
                titleList.Add(new string[2] {
                    "0000000100000046", "6944"
                });
                break;

            case "4.2E":
                // System Menu
                titleList.Add(new string[2] {
                    "0000000100000002", "482"
                });
                // IOS70
                titleList.Add(new string[2] {
                    "0000000100000046", "6944"
                });
                break;

            case "4.3J":
                // System Menu
                titleList.Add(new string[2] {
                    "0000000100000002", "512"
                });
                // IOS80
                titleList.Add(new string[2] {
                    "0000000100000050", "6944"
                });
                break;

            case "4.3U":
                // System Menu
                titleList.Add(new string[2] {
                    "0000000100000002", "513"
                });
                // IOS80
                titleList.Add(new string[2] {
                    "0000000100000050", "6944"
                });
                break;

            case "4.3E":
                // System Menu
                titleList.Add(new string[2] {
                    "0000000100000002", "514"
                });
                // IOS80
                titleList.Add(new string[2] {
                    "0000000100000050", "6944"
                });
                break;

            default:
                throw new Exception("Invalid System Menu !!");
            }

            // Full list of usefull IOS
            if (this.fullNand)
            {
                // IOS28
                titleList.Add(new string[2] {
                    "000000010000001C", "1807"
                });
                // IOS31
                titleList.Add(new string[2] {
                    "000000010000001F", "3608"
                });
                // IOS33
                titleList.Add(new string[2] {
                    "0000000100000021", "3608"
                });
                // IOS34
                titleList.Add(new string[2] {
                    "0000000100000022", "3608"
                });
                // IOS35
                titleList.Add(new string[2] {
                    "0000000100000023", "3608"
                });
                // IOS36
                titleList.Add(new string[2] {
                    "0000000100000024", "3608"
                });
                // IOS37
                titleList.Add(new string[2] {
                    "0000000100000025", "5663"
                });
                // IOS38
                titleList.Add(new string[2] {
                    "0000000100000026", "4124"
                });
                // IOS53
                titleList.Add(new string[2] {
                    "0000000100000035", "5663"
                });
                // IOS55
                titleList.Add(new string[2] {
                    "0000000100000037", "5663"
                });
                // IOS56
                titleList.Add(new string[2] {
                    "0000000100000038", "5662"
                });
                // IOS57
                titleList.Add(new string[2] {
                    "0000000100000039", "5919"
                });
                // IOS61
                titleList.Add(new string[2] {
                    "000000010000003D", "5662"
                });
            }

            IAsyncResult r = this.BeginInvoke(delegateMethodeGlobalProgress, ((titleList.Count * 2) + 1));

            this.EndInvoke(r);

            delegateMethodeGlobalProgress = new objectInvoker(this.updateGlobalProgress);

            try
            {
                int cptProgress = 0;

                foreach (string[] title in titleList)
                {
                    string currentWadFileName = String.Format("{0}v{1}.wad", title[0], title[1]);

                    if (!isStopRequired)
                    {
                        if (title[0] == "0000000100000002")
                        {
                            this.Invoke(delegateMethodeLabelLog, "Downloading System Menu " + this.sysMenu);
                        }
                        else
                        {
                            this.Invoke(delegateMethodeLabelLog, "Downloading IOS" + Wii.Tools.HexStringToInt(title[0].Substring(8)) + "v" + title[1]);
                        }

                        nusClient.DownloadTitle(title[0], title[1], tmpPath, StoreType.WAD);

                        cptProgress++;
                        this.Invoke(delegateMethodeGlobalProgress, cptProgress);
                    }
                    else
                    {
                        break;
                    }

                    if (!isStopRequired)
                    {
                        this.Invoke(delegateMethodeLabelLog, "Installing Downloaded File");
                        this.Invoke(delegateMethodeLog, "Installing Downloaded File");

                        Wii.WadUnpack.UnpackToNand(tmpPath + currentWadFileName, this.nandPath);
                    }
                    else
                    {
                        break;
                    }

                    if (!isStopRequired)
                    {
                        this.Invoke(delegateMethodeLabelLog, "Delete Temporary Downloaded File");
                        this.Invoke(delegateMethodeLog, "Delete Temporary Downloaded File");

                        File.Delete(tmpPath + currentWadFileName);

                        cptProgress++;
                        this.Invoke(delegateMethodeGlobalProgress, cptProgress);
                    }
                    else
                    {
                        break;
                    }
                }

                if (!isStopRequired)
                {
                    this.Invoke(delegateMethodeLabelLog, "Generate setting.txt");
                    this.Invoke(delegateMethodeLog, "Generate setting.txt");

                    SettingTxt.GenerateFile(this.wiiSerialNumber, this.sysMenu[3].ToString(),
                                            this.nandPath + Path.DirectorySeparatorChar + "title" + Path.DirectorySeparatorChar + "00000001" +
                                            Path.DirectorySeparatorChar + "00000002" + Path.DirectorySeparatorChar + "data");

                    cptProgress++;
                    this.Invoke(delegateMethodeGlobalProgress, cptProgress);
                }

                if (!isStopRequired)
                {
                    this.Invoke(delegateMethodeLabelLog, "Build successfull !");
                    this.Invoke(delegateMethodeLog, "Build successfull !");
                }
                else
                {
                    this.Invoke(delegateMethodeLabelLog, "Build aborted !");
                    this.Invoke(delegateMethodeLog, "Build aborted !");
                }
            }
            catch (Exception ex)
            {
                if (this.IsHandleCreated)
                {
                    this.Invoke(delegateMethodeLabelLog, ex.Message);
                    this.Invoke(delegateMethodeLog, "Build aborted !");
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            finally
            {
                if (this.IsHandleCreated)
                {
                    resetFormInvoker rst = new resetFormInvoker(this.LockUnlockForm);
                    this.Invoke(rst);
                }
            }
        }