     {:ok, %{adapter: adapter}}
   end
 
-  def handle_call({:request, method, url, body, headers, opts}, _from, %{adapter: adapter} = state) do
-    res = case @adapter.request(adapter, method, url, body, headers, opts) do
+  def handle_call({:request, _, _, _, _, _} = req, _from, state) do
+    {:request, method, url, body, headers, opts} = req
+    args = [state.adapter, method, url, body, headers, opts]
+    res = case apply(@adapter, :request, args) do
       {:ok, %Response{}} = res -> res
       {:error, _} = res -> res
     end
     {:reply, res, state}
   end
 
-  def handle_call({:download_file, {url, path, progress_callback, payload, headers, stream_fun}}, _from, %{adapter: adapter} = state) do
-    res = case @adapter.download_file(adapter, url, path, progress_callback, payload, headers, stream_fun) do
+  def handle_call({:download_file, call}, _from, %{adapter: adapter} = state) do
+    {url, path, progress_callback, payload, headers, stream_fun} = call
+    args = [adapter, url, path, progress_callback, payload, headers, stream_fun]
+    res = case apply(@adapter, :download_file, args) do
       {:ok, _} = res -> res
       {:error, _} = res -> res
     end
     {:reply, res, state}
   end
 
-  def handle_call({:upload_file, {path, meta}}, _from, %{adapter: adapter} = state) do
-    res = case @adapter.upload_file(adapter, path, meta || %{x: -1, y: -1, z: -1}) do
+  def handle_call({:upload_file, {path, meta}}, _from, state) do
+    meta_arg = meta || %{x: -1, y: -1, z: -1}
+    args = [state.adapter, path, meta_arg]
+    res = case apply(@adapter, :upload_file, args) do
       {:ok, _} = res -> res
       {:error, _} = res -> res
     end


  def request!(method, url, body, headers, opts) do
    case request(method, url, body, headers, opts) do
      {:ok, %Response{status_code: code} = resp} when code > 199 and code < 300 -> resp
      {:ok, %Response{} = resp} -> raise Error, resp

      {:error, reason} -> raise Error, reason

  * opts     - Keyword opts to be passed to adapter (hackney/httpoison)
    * `file` - option to  be passed if the output should be saved to a file.
  """
  @spec request(method, url, body, headers, opts)
    :: {:ok, Response.t} | {:error, term}
  def request(method, url, body \\ "", headers \\ [], opts \\ [])

  def request(method, url, body, headers, opts) do
    call = {:request, method, url, body, headers, opts}
    GenServer.call(__MODULE__, call, :infinity)
  end

  @doc "Same as `request/5` but raises."
