   defp transform_values([{k, v} | rest], options, acc) do
     atom_k = String.to_existing_atom(k)
 
-    case ValueTransformer.transform_value(k, String.trim(v), options[atom_k]) do
+    case ValueTransformer.transform_value(k, v, options[atom_k]) do
       {:error, _} = error -> error
       value -> transform_values(rest, options, [{atom_k, value} | acc])
     end

  @spec split_kv(binary) :: {binary, binary}

  defp split_kv(line) do
    case String.split(line, ":", parts: 2) do
      [x] -> {String.trim(x), ""}
      [k, v] -> {k, v}
    end
  end

  def parse_header(data, options, required \\ []) do
    case extract_header(data, [], false) do
      {:ok, header_lines, rest_data} ->
        key_strings = options |> Keyword.keys() |> Enum.map(&to_string/1)
        req_strings = Enum.map(required, &to_string/1)

        kv_lists =
          header_lines
          |> Enum.map(&split_kv/1)
          |> Enum.group_by(&(elem(&1, 0) in key_strings))

        %{
          true: accepted_kv,
          false: extra_kv
        } = Map.merge(%{true: [], false: []}, kv_lists)

        with [] <- find_missing(accepted_kv, req_strings),
             {:ok, parsed} <- transform_values(accepted_kv, options, []) do
          extras =
            Enum.map(extra_kv, fn {k, v} ->
              {k, ValueTransformer.transform_value(k, v, :string)}
            end)

          {:ok, {Map.new(parsed), Map.new(extras), rest_data}}
        else
          error -> handle_error(error)
        end
