 defmodule Credo.Check.Consistency.Collector do
   @moduledoc """
-  `Collector` is a behavior for consistency check modules
-  that run on all source files.
+  A behavior for modules that walk through source files and
+  identify consistency issues.
+
+  When defining a consistency check, you would typically use
+  this structure for the main module, responsible
+  for formatting issue messages:
+
+      defmodule Credo.Check.Consistency.SomeCheck do
+        use Credo.Check, run_on_all: true
+
+        @collector Credo.Check.Consistency.SomeCheck.Collector
+
+        def run(source_files, exec, params \\ []) when is_list(source_files) do
+          issue_formatter = &issues_for/3
+          @collector.create_issues(source_files, exec, params, issue_formatter)
+        end
+
+        defp issues_for(expected, source_file, params) do
+          issue_meta = IssueMeta.for(source_file, params)
+          issue_locations =
+            @collector.find_locations_not_matching(expected, source_file)
+
+          Enum.map(issue_locations, fn(location) ->
+            format_issue issue_meta, message: ... # write an issue message
+          end)
+        end
+
+  The actual analysis would be performed by another module
+  implementing the `Credo.Check.Consistency.Collector` behavior:
+
+      defmodule Credo.Check.Consistency.SomeCheck.Collector do
+        use Credo.Check.Consistency.Collector
+
+        def collect_matches(source_file, params), do ...
+
+        def find_locations_not_matching(expected, source_file), do ...
+      end
+
+  Read further for more information on `collect_matches/2`,
+  `find_locations_not_matching/2`, and `issue_formatter`.
   """
 
   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` on them (see below).

  `issue_formatter` functions may call `find_locations_not_matching`
  to obtain additional metadata for each occurrence of
  an unexpected match in a given file.
  """
  @callback find_locations_not_matching(
    expected :: term, source_file :: SourceFile.t) :: list(term)

  @optional_callbacks find_locations_not_matching: 2

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

  defmacro __using__(_opts) do
    quote do

  alias Credo.Execution.Issues

  @doc """
  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.

  `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.
