   alias Credo.Execution.Issues
 
   @doc """
-  The first step of a `Collector` run is counting occurrences of matches
-  (e.g. :with_space and :without_space for a space around operators check).
+  When you call `@collector.create_issues/4` inside the check module,
+  the collector first counts the occurrences of different matches
+  (e.g. :with_space and :without_space for a space around operators check)
+  per each source file.
 
-  This function produces a map of matches as keys and their frequencies
-  as values (e.g. %{with_space: 50, without_space: 40}) for a single source
-  file.
+  `collect_matches/2` produces a map of matches as keys and their frequencies
+  as values (e.g. %{with_space: 50, without_space: 40}).
 
   The maps for individual source files are then merged, producing a map
   that reflects frequency trends for the whole codebase.

defmodule Credo.Check.Consistency.Collector do
  @moduledoc """
  `Collector` is a behavior for consistency check modules
  that run on all source files.
  """

  alias Credo.Issue

  Once the most frequent match is identified, the `Collector` looks up
  source files that have other matches (e.g. both :with_space
  and :without_space or just :without_space when :with_space is the
  most frequent) and calls the `issue_formatter` function on them.

  An issue formatter produces a list of `Credo.Issue` structs
  from the most frequent (expected) match, a source file
  containing other matches, and check params
  (the latter two are required to build an IssueMeta).
  """
  @type issue_formatter :: (term, SourceFile.t, Keyword.t -> [Issue.t])

  @doc """
  `issue_formatter` may call the `@collector.find_locations_not_matching/2`
  function to obtain additional metadata for each occurrence of
  an unexpected match in a given file.

  An example implementation that returns a list of line numbers on
  which unexpected occurrences were found:

      def find_locations_not_matching(expected, source_file) do
        traverse(source_file, fn(match, line_no, acc) ->
          if match != expected, do: acc ++ [line_no], else: acc
        end)
      end

      defp traverse(source_file, fun), do: ...
  """
  @callback find_locations_not_matching(
    expected :: term, source_file :: SourceFile.t) :: list(term)

  @optional_callbacks find_locations_not_matching: 2

  defmacro __using__(_opts) do
    quote do
