 
   """
   def parse(argv, opts \\ []) when is_list(argv) and is_list(opts) do
-    config = compile_config(opts, all: true)
+    config =
+      Keyword.merge(opts, [all: true, strict: false])
+      |> compile_config()
     do_parse(argv, config, [], [], [])
   end
 

  Low-level function that parses one option.
  """
  def next(argv, opts \\ []) when is_list(argv) and is_list(opts) do
    {aliases, switches, _} = compile_config(opts, false)
    next(argv, aliases, switches)
  end

  defp next([], _aliases, _switches) do
    {:error, []}
  end

  defp next(["--"|_]=argv, _aliases, _switches) do
    {:error, argv}
  end

  defp next(["-" <> option|rest], aliases, switches) do
    {option, value} = split_option(option)
    {option, kinds, value} = normalize_option(option, value, switches, aliases)

    #FIXME: don't modify rest for unknown options in strict mode
    {value, kinds, rest} = normalize_value(value, kinds, rest)

    case validate_option(option, value, kinds) do
      {:ok, new_value} ->
        {:ok, option, new_value, rest}

      :invalid ->
        {:error, option, value, rest}
    end
  end

  defp next(argv, _aliases, _switches) do
    {:error, argv}
  end

  ## Helpers

  defp compile_config(opts, all: flag) do
    aliases  = opts[:aliases]  || []
    switches = opts[:switches] || []
    {aliases, switches, flag}
  end

  defp validate_option(option, value, kinds) do

    {Enum.reverse(opts), Enum.reverse(args), Enum.reverse(invalid)}
  end

  defp do_parse(argv, {aliases, switches, strict, all}=config, opts, args, invalid) do
    case next(argv, aliases, switches, strict) do
      {:ok, option, value, rest} ->
        # the option exist and it was successfully parsed
        kinds = List.wrap Keyword.get(switches, option)
        new_opts = do_store_option(opts, option, value, kinds)
        do_parse(rest, config, new_opts, args, invalid)

      {:error, {:value, option, value}, rest} ->
        # the option exist but it has wrong value
        do_parse(rest, config, opts, args, [{option, value}|invalid])

      {:error, {:undefined, option, value}, rest} ->
        # the option does not exist (for strict cases)
        do_parse(rest, config, opts, args, [{option, value}|invalid])

      {:error, ["--"|rest]} ->
        {Enum.reverse(opts), Enum.reverse(args, rest), Enum.reverse(invalid)}
