# File lib/cri/base.rb, line 22
    def run(args)
      # Check arguments
      if args.length == 0
        @help_command.run([], [])
        exit 1
      end

      # Partition options
      opts_before_command         = []
      command_name                = nil
      opts_and_args_after_command = []
      stage = 0
      args.each do |arg|
        # Update stage if necessary
        stage = 1 if stage == 0 && !is_option?(arg)

        # Add
        opts_before_command << arg         if stage == 0
        command_name = arg                 if stage == 1
        opts_and_args_after_command << arg if stage == 2

        # Update stage if necessary
        stage = 2 if stage == 1
      end

      # Handle options before command
      begin
        parsed_arguments = Cri::OptionParser.parse(opts_before_command, global_option_definitions)
      rescue Cri::OptionParser::IllegalOptionError => e
        $stderr.puts "illegal option -- #{e}"
        exit 1
      end
      parsed_arguments[:options].keys.each do |option|
        handle_option(option)
      end

      # Get command
      if command_name.nil?
        $stderr.puts "no command given"
        exit 1
      end
      command = command_named(command_name)
      if command.nil?
        $stderr.puts "no such command: #{command_name}"
        exit 1
      end

      # Parse arguments
      option_definitions = command.option_definitions + global_option_definitions
      begin
        parsed_arguments = Cri::OptionParser.parse(opts_and_args_after_command, option_definitions)
      rescue Cri::OptionParser::IllegalOptionError => e
        $stderr.puts "illegal option -- #{e}"
        exit 1
      rescue Cri::OptionParser::OptionRequiresAnArgumentError => e
        $stderr.puts "option requires an argument -- #{e}"
        exit 1
      end

      # Handle global options
      global_options = global_option_definitions.map { |o| o[:long] }
      global_options.delete_if { |o| !parsed_arguments[:options].keys.include?(o.to_sym) }
      global_options.each { |o| handle_option(o.to_sym) }

      if parsed_arguments[:options].has_key?(:help)
        # Show help for this command
        show_help(command)
      else
        # Run command
        command.run(parsed_arguments[:options], parsed_arguments[:arguments])
      end
    end