 
   # Upcase
 
-  def upcase(string), do: upcase(string, "")
+  def upcase(string) when is_binary(string), do: upcase(string, "")
 
   for {codepoint, upper, _lower, _title} <- codes, upper && upper != codepoint do
-    defp upcase(unquote(codepoint) <> rest, acc) do
+    defp upcase(<<unquote(codepoint), rest::bits>>, acc) do
       upcase(rest, acc <> unquote(upper))
     end
   end
 
-  defp upcase(<<char, rest::binary>>, acc) do
+  defp upcase(<<char, rest::bits>>, acc) do
     upcase(rest, <<acc::binary, char>>)
   end
 


  # Downcase

  def downcase(string), do: downcase(string, "")

  for {codepoint, _upper, lower, _title} <- codes, lower && lower != codepoint do
    defp downcase(unquote(codepoint) <> rest, acc) do
      downcase(rest, acc <> unquote(lower))
    end
  end

  defp downcase(<<char, rest::binary>>, acc) do
    downcase(rest, <<acc::binary, char>>)
  end



  # trim_leading

  def trim_leading(string) when is_binary(string) do
    do_trim_leading(string)
  end

  for codepoint <- whitespace do
    def do_trim_leading(<<unquote(codepoint), rest::bits>>), do: do_trim_leading(rest)
  end
  def do_trim_leading(<<rest::bits>>), do: rest

  # trim_trailing

