public CommandLineParser()
        {
            bootloader_operations = new List <en_bootloader_operations>();
            bootloader_passwords  = new List <string>();

            /* set defaults */
            verbose_output  = false;
            prewait_ms      = default_prewait_ms;
            replytimeout_ms = default_replytimeout_ms;
            activation_mode = en_bootloader_activation_mode.COLD_BOOT; // default is cold boot

            dynid = -1;
        }
        public bool parse_command_line(String[] args)
        {
            if (args.Count() == 0)
            {
                display_usage();
                return(false);
            }

            foreach (string s in args)
            {
                string[] split = s.Split('=');
                if (split.Count() > 2)
                {
                    throw_error_invalid_param(s);
                    return(false);
                }
                else if (split.Count() == 1)
                {
                    switch (split[0].ToLower())
                    {
                    case "-?":
                    case "-h":
                        display_usage();
                        return(false);

                    case "-xxx":
                        bootloader_operations.Add(en_bootloader_operations.EMERGENCY_ERASE);
                        xxx_found_ = true;
                        break;

                    case "-tagefile":
                        if (tagefile_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        tag_eepromfilename_withdatetimepwd = true;
                        tagefile_found_ = true;
                        break;

                    case "-tagffile":
                        if (tagffile_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        tag_flashfilename_withdatetimepwd = true;
                        tagffile_found_ = true;
                        break;

                    case "-patchdaisychain":
                        if (patch_daisychain_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        bootloader_operations.Add(en_bootloader_operations.PATCH_DAISY_CHAIN_BUG);
                        patch_daisychain_found_ = true;
                        break;

                    case "-i":
                        if (display_device_info_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        display_device_info_found_ = true;
                        bootloader_operations.Add(en_bootloader_operations.DISPLAY_DEVICE_INFO);
                        break;

                    case "-v":
                        if (verbose_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        display_device_info_found_ = true;
                        verbose_output             = true;
                        break;

                    default:
                        throw_error_invalid_param(s);
                        return(false);
                    }
                }
                else   /* we have precisely 2 arguments */
                {
                    switch (split[0].ToLower())
                    {
                    case "-port":
                        if (port_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        port_name = split[1];

                        if (port_name.Length == 0)
                        {
                            throw_error("Port name is not correctly specified.");
                            return(false);
                        }

                        port_found_ = true;
                        break;

                    case "-baud":
                        if (baud_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        if (!int.TryParse(split[1], out baudrate_bps))
                        {
                            throw_error(string.Format("Invalid argument '{0}' passed to '{1}'.", split[1], split[0]));
                            return(false);
                        }
                        else
                        {
                            /* if it success, the baud rate is already stored in baudrate_bps */
                            baud_found_ = true;
                        }

                        baudrate_bps = Math.Abs(baudrate_bps);      /* ensure we use a positive number */

                        break;

                    case "-acmode":
                        if (acmode_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        split[1] = split[1].ToLower();

                        if (split[1] == "cold")
                        {
                            activation_mode = en_bootloader_activation_mode.COLD_BOOT;
                            acmode_found_   = true;
                        }
                        else if (split[1] == "live")
                        {
                            activation_mode = en_bootloader_activation_mode.LIVE_VIA_DYNAMIXEL;
                            acmode_found_   = true;
                        }
                        else
                        {
                            throw_error(string.Format("Invalid argument '{0}' passed to '{1}'. Must be 'cold' or 'live'.", split[1], split[0]));
                            return(false);
                        }
                        break;

                    case "-dynid":
                        if (dynid_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        if (!int.TryParse(split[1], out dynid))
                        {
                            throw_error(string.Format("Invalid argument '{0}' passed to '{1}'.", split[1], split[0]));
                            return(false);
                        }
                        else
                        {
                            /* if it success, it is already stored  */
                            dynid_found_ = true;
                        }
                        break;

                    case "-prewait":
                        if (prewait_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        if (!int.TryParse(split[1], out prewait_ms))
                        {
                            throw_error(string.Format("Invalid argument '{0}' passed to '{1}'.", split[1], split[0]));
                            return(false);
                        }
                        else
                        {
                            /* if it success, it is already stored */
                            prewait_found_ = true;
                        }

                        prewait_ms = Math.Abs(prewait_ms);      /* ensure we use a positive number */
                        break;

                    case "-replytimeout":
                        if (timeout_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        if (!int.TryParse(split[1], out replytimeout_ms))
                        {
                            throw_error(string.Format("Invalid argument '{0}' passed to '{1}'.", split[1], split[0]));
                            return(false);
                        }
                        else
                        {
                            /* if it success, the baud rate is already stored in baudrate_bps */
                            timeout_found_ = true;
                        }

                        replytimeout_ms = Math.Abs(replytimeout_ms);      /* ensure we use a positive number */
                        break;

                    case "-fop":
                        if (fop_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }

                        foreach (char c in split[1].ToLower())
                        {
                            switch (c)
                            {
                            case 'e':
                                bootloader_operations.Add(en_bootloader_operations.FW_ERASE);
                                break;

                            case 'w':
                                bootloader_operations.Add(en_bootloader_operations.FW_WRITE);
                                break;

                            case 'v':
                                bootloader_operations.Add(en_bootloader_operations.FW_VERIFY);
                                break;

                            case 'r':
                                bootloader_operations.Add(en_bootloader_operations.FW_READ);
                                break;

                            default:
                                throw_error(string.Format("Invalid option '{0}' specified for '{1}'", c, split[0]));
                                return(false);
                            }
                        }
                        fop_found_ = true;
                        break;

                    case "-eop":
                        if (eop_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }

                        foreach (char c in split[1].ToLower())
                        {
                            switch (c)
                            {
                            case 'e':
                                bootloader_operations.Add(en_bootloader_operations.EEP_ERASE);
                                break;

                            case 'w':
                                bootloader_operations.Add(en_bootloader_operations.EEP_WRITE);
                                break;

                            case 'v':
                                bootloader_operations.Add(en_bootloader_operations.EEP_VERIFY);
                                break;

                            case 'r':
                                bootloader_operations.Add(en_bootloader_operations.EEP_READ);
                                break;

                            default:
                                throw_error(string.Format("Invalid option '{0}' specified for '{1}'", c, split[0]));
                                return(false);
                            }
                        }
                        eop_found_ = true;
                        break;

                    case "-xop":
                        if (xop_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }

                        foreach (char c in split[1].ToLower())
                        {
                            switch (c)
                            {
                            case 't':
                                bootloader_operations.Add(en_bootloader_operations.TIMEOUT_CHANGE);
                                break;

                            case 'p':
                                bootloader_operations.Add(en_bootloader_operations.PASSWORD_CHANGE);
                                break;

                            case 'm':
                                bootloader_operations.Add(en_bootloader_operations.WRITE_MAGIC_BYTES);
                                break;


                            default:
                                throw_error(string.Format("Invalid option '{0}' specified for '{1}'", c, split[0]));
                                return(false);
                            }
                        }
                        xop_found_ = true;
                        break;

                    case "-pwd":
                        if (pwd_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        string[] pwd_split = split[1].Split(',');

                        foreach (string pwd in pwd_split)
                        {
                            if (bootloader_passwords.Contains(pwd))
                            {
                                throw_error(string.Format("Password '{0}' is specified at least twice. Please specify each password only once.", pwd));
                                return(false);
                            }
                            bootloader_passwords.Add(pwd);
                        }
                        pwd_found_ = true;
                        break;

                    case "-ffile":
                        if (ffile_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        flash_file_name = split[1];
                        ffile_found_    = true;
                        break;

                    case "-efile":
                        if (efile_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }
                        eeprom_file_name = split[1];
                        efile_found_     = true;
                        break;

                    case "-seederos":
                        if (seederos_found_)
                        {
                            throw_error_duplicate_param(split[0]); return(false);
                        }

                        if (split[1].ToLower().Equals("bron") || split[1].ToLower().Equals("bren"))      /* we'll keep 'bren' for legacy purposes but hanging for 'bron' for future */
                        {
                            bootloader_operations.Add(en_bootloader_operations.SEEDEROS_BRIDGEENABLE);
                        }
                        else if (split[1].ToLower().Equals("broff"))
                        {
                            bootloader_operations.Add(en_bootloader_operations.SEEDEROS_BRIDGEDISABLE);
                        }
                        else
                        {
                            throw_error(string.Format("Invalid option '{0}' specified for '{1}'", split[1], split[0]));
                            return(false);
                        }
                        seederos_found_ = true;
                        break;

                    default:
                        throw_error_invalid_param(split[0]);
                        return(false);
                    }
                }
            }

            if (!port_found_)
            {
                throw_error(string.Format("Missing mandatory parameter '-port'{0}The serial port name must be specified for all operations.", Environment.NewLine));
                return(false);
            }

            /* if using seederos, the baud is not mandatory */
            if (!baud_found_ && !seederos_found_)
            {
                throw_error(string.Format("Missing mandatory parameter '-baud'{0}With the release of fixed baud versions bootloader versions, baud rate must now be explicitly specified (tip: old default was 9600 bps).", Environment.NewLine));
                return(false);
            }

            if (xxx_found_ && bootloader_operations.Count() > 1)
            {
                /* xxx was specified but other operations were specified too.
                 * This is an incorrect behaviour. XXX must be used alone
                 */
                throw_error("The '-XXX' command option can only be used alone. It can't be combined with -fop, -eop, -xop or -seederos.");
                return(false);
            }

            if (seederos_found_ && bootloader_operations.Count() > 1)
            {
                /* xxx was specified but other operations were specified too.
                 * This is an incorrect behaviour. XXX must be used alone
                 */
                throw_error("The '-seederos' command option can only be used alone. It can't be combined with -fop, -eop, -xop or -XXX.");
                return(false);
            }


            return(true);
        }