     end
   end
 
-  defp normalize_option(<<?-, option :: binary>>, value, switches, _aliases) do
-    normalize_option(get_negated(option, switches), value, switches)
-  end
-
-  defp normalize_option(option, value, switches, aliases) do
-    option = get_option(option)
-    if alias = aliases[option] do
-      normalize_option({:default, alias}, value, switches)
+  defp tag_option(<<?-, option :: binary>>, switches, _aliases) do
+    get_negated(option, switches)
+  end
+
+  defp tag_option(option, _switches, aliases) when is_binary(option) do
+    opt = get_option(option)
+    if alias = aliases[opt] do
+      {:default, alias}
     else
-      {option, [:invalid], value}
-    end
+      {:unknown, opt}
+    end
+  end
+
+  defp option_defined?({:unknown, _option}, _switches) do
+    false
+  end
+
+  defp option_defined?({:negated, option}, switches) do
+    Keyword.has_key?(switches, option)
+  end
+
+  defp option_defined?({:default, option}, switches) do
+    Keyword.has_key?(switches, option)
+  end
+
+  defp normalize_option({:unknown, option}, value, _switches) do
+    {option, [:invalid], value}
   end
 
   defp normalize_option({:negated, option}, nil, switches) do

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

  defp do_parse(argv, {aliases, switches, all}=config, opts, args, invalid) do
    case next(argv, aliases, switches) 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, option, value, rest} ->
        # the option exist but it has wrong value
        do_parse(rest, config, opts, args, [{option, value}|invalid])

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

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


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

