class RuboCop::Cop::Commissioner

work to the specified cops.
Commissioner class is responsible for processing the AST and delegating

def initialize(cops, forces = [], options = {})

def initialize(cops, forces = [], options = {})
  @cops = cops
  @forces = forces
  @options = options
  @callbacks = {}
  reset_errors
end

def investigate(processed_source)

def investigate(processed_source)
  reset_errors
  remove_irrelevant_cops(processed_source.file_path)
  reset_callbacks
  prepare(processed_source)
  invoke_custom_processing(@cops, processed_source)
  invoke_custom_processing(@forces, processed_source)
  walk(processed_source.ast) unless processed_source.blank?
  @cops.flat_map(&:offenses)
end

def invoke_custom_processing(cops_or_forces, processed_source)

its own processing.
to the commissioner will be passed to the cop too in order to do
If they define the #investigate method, all input parameters passed
There are cops/forces that require their own custom processing.
def invoke_custom_processing(cops_or_forces, processed_source)
  cops_or_forces.each do |cop|
    next unless cop.respond_to?(:investigate)
    with_cop_error_handling(cop) do
      cop.investigate(processed_source)
    end
  end
end

def prepare(processed_source)

TODO: Bad design.
def prepare(processed_source)
  @cops.each { |cop| cop.processed_source = processed_source }
end

def remove_irrelevant_cops(filename)

def remove_irrelevant_cops(filename)
  @cops.reject! { |cop| cop.excluded_file?(filename) }
  @cops.reject! do |cop|
    cop.class.respond_to?(:support_target_ruby_version?) &&
      !cop.class.support_target_ruby_version?(cop.target_ruby_version)
  end
  @cops.reject! do |cop|
    cop.class.respond_to?(:support_target_rails_version?) &&
      !cop.class.support_target_rails_version?(cop.target_rails_version)
  end
end

def reset_callbacks

def reset_callbacks
  @callbacks.clear
end

def reset_errors

def reset_errors
  @errors = Hash.new { |hash, k| hash[k] = [] }
end

def trigger_responding_cops(callback, node)

def trigger_responding_cops(callback, node)
  @callbacks[callback] ||= @cops.select do |cop|
    cop.respond_to?(callback)
  end
  @callbacks[callback].each do |cop|
    with_cop_error_handling(cop, node) do
      cop.send(callback, node)
    end
  end
end

def with_cop_error_handling(cop, node = nil)

cops' `#investigate` methods.
re-raising exceptions that can be raised from within the individual
Allow blind rescues here, since we're absorbing and packaging or
def with_cop_error_handling(cop, node = nil)
  yield
rescue StandardError => e
  raise e if @options[:raise_error]
  if node
    line = node.first_line
    column = node.loc.column
  end
  error = CopError.new(e, line, column)
  @errors[cop] << error
end