          [elixirc_watch_exts: [:ex, :eex]]
 
   """
+
+  @switches [force: :boolean, quick: :boolean, docs: :boolean,
+             ignore_module_conflict: :boolean, debug_info: :boolean,
+             warnings_as_errors: :boolean]
+
   def run(args) do
-    { opts, _ } = OptionParser.parse(args, aliases: [q: :quick],
-                    switches: [force: :boolean, quick: :boolean])
+    { opts, _ } = OptionParser.parse(args, aliases: [q: :quick], switches: @switches)
 
     project       = Mix.project
     compile_path  = project[:compile_path]


    if opts[:force] or stale != [] do
      File.mkdir_p! compile_path
      compile_files opts[:quick], project, compile_path, to_compile, stale
      :ok
    else
      :noop
    end
  end

  defp compile_files(true, project, compile_path, to_compile, stale) do
    opts = project[:elixirc_options] || []
    opts = Keyword.put(opts, :ignore_module_conflict, true)
    Code.compiler_options(opts)
    to_compile = lc f inlist to_compile, f in stale, do: f
    compile_files(to_compile, compile_path)
    File.touch! Path.join(compile_path, @manifest)
  end

  defp compile_files(false, project, compile_path, to_compile, _stale) do
    Code.delete_path compile_path
    opts = project[:elixirc_options] || []
    Code.compiler_options(opts)

    { _current, to_remove } =
      Mix.Utils.manifest Path.join(compile_path, @manifest), fn ->

    Code.prepend_path compile_path
  end

  defp set_compiler_opts(project, opts, extra) do
    opts = Dict.take(opts, [:docs, :debug_info, :ignore_module_conflict, :warnings_as_errors])
    opts = Keyword.merge(project[:elixirc_options] || [], opts)
    Code.compiler_options Keyword.merge(opts, extra)
  end

  defp compile_files(files, to) do
    Kernel.ParallelCompiler.files_to_path files, to, fn(x) ->
      Mix.shell.info "Compiled #{x}"
