Parses the command-line arguments to this script, and parse the given
      configuration file (if any).  Returns a Namespace containing the resulting
      options. This method will use the configuration file parameters if any exist,
      otherwise it will use the command-line arguments.

def parse_args(self):
      """Parses the command-line arguments to this script, and parse the given
      configuration file (if any).  Returns a Namespace containing the resulting
      options. This method will use the configuration file parameters if any exist,
      otherwise it will use the command-line arguments."""
      # Parse sys.argv
      cli_args = self.parser.parse_args()

      if cli_args.config:
         # Parse the configuration file
         config_file = open(cli_args.config, 'r')
         config_json = json.load(config_file)
         config_opts = config_json.get('options', {})

         # Validate the configuration file
         ConfigurationValidator.validate_config_json(config_json)

         # Turn JSON options into a flat list of strings for the parser
         args = reduce(lambda l, t: l + [str(t[0]), str(t[1])], config_opts.items(), [])
         args = filter(lambda x: x is not None, args)

         # Pass the configuration file options to the parser
         config_args = self.parser.parse_args(args=args)
         config_args.tests = config_json.get('tests', [])
         config_args.configuration = config_json.get('configuration', {})
         config_args.environments = config_json.get('environments', [])

         args = config_args
      else:
         args = cli_args

      
      if args.log_level == "INFO":
          args.log_level = LogLevel.INFO
      elif args.log_level == "WARN":
          args.log_level = LogLevel.WARN
      elif args.log_level == "DEBUG":
          args.log_level = LogLevel.DEBUG
      else:
          args.log_level = LogLevel.ERROR

      return args