   and never returns `:timeout` or `:stop`.
   """
   def pdus(esme, timeout \\ @default_timeout) do
-    ESME.call(esme, :pdus, timeout)
+    Session.call(esme, :pdus, timeout)
   end
 
   @spec stop(esme :: pid) :: :ok
 
   @doc """
-  Stops ESME asyncronously.
+  Stops ESME syncronously.
   """
   def stop(esme) do
-    ESME.stop(esme)
+    Session.stop(esme)
   end
 
   # ESME callbacks
 
   @doc false
-  def handle_call({:request, pdu}, from, st) do
-    ESME.send_pdu(self(), pdu)
+  def handle_call({:call, {:request, pdu}, from}, _from, st) do
     new_st = %{st | from: from, pdu: pdu, state: :wait_for_resp}
-    {:noreply, new_st}
+    {:reply, :ok, [pdu], new_st}
   end
 
   def handle_call(:pdus, _from, st) do
-    do_get_pdus(st)
-  end
-
-  def handle_call(:wait_for_pdus, from, st) do
-    case st.additional_pdus do
-      [_ | _] -> do_get_pdus(st)
+    pdus = Enum.reverse(st.additional_pdus)
+    new_st = %{st | additional_pdus: []}
+    {:reply, pdus, new_st}
+  end
+
+  def handle_call({:call, :wait_for_pdus, from}, _from, st) do
+    new_st = case st.additional_pdus do
+      [_ | _] ->
+        pdus = Enum.reverse(st.additional_pdus)
+        reply(from, pdus)
+        %{st | additional_pdus: []}
       [] ->
-        new_st = %{st | from: from, state: :wait_for_pdus}
-        {:noreply, new_st}
-    end
+        %{st | from: from, state: :wait_for_pdus}
+    end
+    {:reply, :ok, new_st}
   end
 
   @doc false
   def handle_resp(pdu, original_pdu, st) do
     case st.pdu != nil and Pdu.same?(original_pdu, st.pdu) and st.state == :wait_for_resp do
       true ->
-        GenServer.reply(st.from, {:ok, pdu})
-        do_set_free(st)
+        reply(st.from, {:ok, pdu})
+        {:ok, set_free(st)}
       false ->
-        do_push_to_waiting({:resp, pdu, original_pdu}, st)
+        {:ok, push_to_waiting({:resp, pdu, original_pdu}, st)}
     end
   end
 


  """
  def wait_for_pdus(esme, timeout \\ @default_timeout) do
    try do
      ESME.call(esme, :wait_for_pdus, timeout)
    catch
      :exit, {:timeout, _} -> :timeout
    end
  end

  @spec pdus(esme :: pid, timeout) :: [awaited]

  @doc false
  def handle_send_pdu_result(pdu, result, st) do
    case result do
      :ok -> push_to_waiting({:ok, pdu}, st)
      {:error, error} ->
        case Pdu.same?(pdu, st.pdu) and st.state == :wait_for_resp do
          true ->
            reply(st.from, {:error, error})
            set_free(st)
          false ->
            push_to_waiting({:error, pdu, error}, st)
        end
    end
  end

  defp push_to_waiting(pdu_info, st) do
    pdus = [pdu_info | st.additional_pdus]
    case st.state == :wait_for_pdus do
      true ->
        reply(st.from, pdus)
        %{set_free(st) | additional_pdus: []}
      false ->
        %{st | additional_pdus: pdus}
    end
  end

  defp set_free(st), do: %{st | from: nil, pdu: nil, state: :free}


  defp call(pid, request, timeout) do
    ref = make_ref()
    from = {ref, self()}
    :ok = Session.call(pid, {:call, request, from})
    receive do
      {^ref, response} -> response
    after timeout -> :timeout
    end
  end

  def reply({ref, pid} = _from, response) do
    send(pid, {ref, response})
  end

end
