     timer_ref = Process.send_after(self(), {:timed_out, pid}, timeout)
 
     new_queued = [{pid, ref, h, timer_ref} | queued]
-    spawn_compilers(t, original, output, options, waiting, new_queued, schedulers, result)
+    spawn_compilers(%{state | entries: t, queued: new_queued})
   end
 
   # No more files, nothing waiting, queue is empty, we are done
-  defp spawn_compilers([], _original, _output, _options, [], [], _schedulers, result) do
+  defp spawn_compilers(%{entries: [], waiting: [], queued: [], result: result}) do
     for {:module, mod} <- result, do: mod
   end
 
   # Queued x, waiting for x: POSSIBLE ERROR! Release processes so we get the failures
-  defp spawn_compilers([], original, output, options, waiting, queued, schedulers, result) when length(waiting) == length(queued) do
+  defp spawn_compilers(%{entries: [], waiting: waiting, queued: queued} = state) when length(waiting) == length(queued) do
     entries = for {pid, _, _, _} <- queued,
                   waiting_on_is_not_being_defined?(waiting, pid),
                   do: {pid, :not_found}
 
     case entries do
       [] -> handle_deadlock(waiting, queued)
-      _  -> spawn_compilers(entries, original, output, options, waiting, queued, schedulers, result)
+      _  -> spawn_compilers(%{state | entries: entries})
     end
   end
 
   # No more files, but queue and waiting are not full or do not match
-  defp spawn_compilers([], original, output, options, waiting, queued, schedulers, result) do
-    wait_for_messages([], original, output, options, waiting, queued, schedulers, result)
+  defp spawn_compilers(%{entries: []} = state) do
+    wait_for_messages(state)
   end
 
   defp waiting_on_is_not_being_defined?(waiting, pid) do

            [{kind, child, ref, on, defining} | waiting]
          end

        spawn_compilers(entries, original, output, options, waiting, queued, schedulers, result)

      {:timed_out, child} ->
        if callback = Keyword.get(options, :each_long_compilation) do
          {^child, _, file, _} = List.keyfind(queued, child, 0)
          callback.(file)
        end
        spawn_compilers(entries, original, output, options, waiting, queued, schedulers, result)

      {:DOWN, _down_ref, :process, down_pid, {:shutdown, file}} ->
        if callback = Keyword.get(options, :each_file) do


        cancel_waiting_timer(queued, child)

        spawn_compilers(%{state | entries: available ++ entries, result: [{:module, module} | result]})

      {:waiting, kind, child, ref, on, defining} ->
        defined = fn {k, m} -> on == m and k in [kind, :module] end
