# File lib/cri/option_parser.rb, line 156
    def run
      @running = true

      while running?
        # Get next item
        e = @unprocessed_arguments_and_options.shift
        break if e.nil?

        # Handle end-of-options marker
        if e == '--'
          @no_more_options = true
        # Handle incomplete options
        elsif e =~ /^--./ and !@no_more_options
          # Get option key, and option value if included
          if e =~ /^--([^=]+)=(.+)$/
            option_key   = $1
            option_value = $2
          else
            option_key    = e[2..-1]
            option_value  = nil
          end

          # Find definition
          definition = @definitions.find { |d| d[:long] == option_key }
          raise IllegalOptionError.new(option_key) if definition.nil?

          if [ :required, :optional ].include?(definition[:argument])
            # Get option value if necessary
            if option_value.nil?
              option_value = @unprocessed_arguments_and_options.shift
              if option_value.nil? || option_value =~ /^-/
                if definition[:argument] == :required
                  raise OptionRequiresAnArgumentError.new(option_key)
                else
                  @unprocessed_arguments_and_options.unshift(option_value)
                  option_value = true
                end
              end
            end

            # Store option
            add_option(definition[:long].to_sym, option_value)
          else
            # Store option
            add_option(definition[:long].to_sym, true)
          end
        # Handle -xyz options
        elsif e =~ /^-./ and !@no_more_options
          # Get option keys
          option_keys = e[1..-1].scan(/./)

          # For each key
          option_keys.each do |option_key|
            # Find definition
            definition = @definitions.find { |d| d[:short] == option_key }
            raise IllegalOptionError.new(option_key) if definition.nil?

            if option_keys.length > 1 and definition[:argument] == :required
              # This is a combined option and it requires an argument, so complain
              raise OptionRequiresAnArgumentError.new(option_key)
            elsif [ :required, :optional ].include?(definition[:argument])
              # Get option value
              option_value = @unprocessed_arguments_and_options.shift
              if option_value.nil? || option_value =~ /^-/
                if definition[:argument] == :required
                  raise OptionRequiresAnArgumentError.new(option_key)
                else
                  @unprocessed_arguments_and_options.unshift(option_value)
                  option_value = true
                end
              end

              # Store option
              add_option(definition[:long].to_sym, option_value)
            else
              # Store option
              add_option(definition[:long].to_sym, true)
            end
          end
        # Handle normal arguments
        else
          add_argument(e)
        end
      end
      self
    ensure
      @running = false
    end