         r = task_data |> Tasks.pop_remaining_task
         if is_nil(r) do
             Logger.info "We tried all tasks!"
-            check_offers_finally(task_data)
+            {:next_state, :check_offers_finally,
+             task_data, @check_offers_finally_timeout}
         else
             {t, without_task} = r
-            Logger.info "Only #{length without_task.remaining_tasks} tasks left"
+            Logger.info "Only #{length(without_task.remaining_tasks)+1} tasks left"
             if t != self() do
-                send t, {:go_exchange, self(), without_task}
-                wait_agreement = fn itself ->
-                            receive do
-                                {:go, t, new_data} ->
-                                    Logger.info "go exchenge (is's agrement)!"
-                                    send t, :done
-                                    check_offers(new_data)
-                                :no ->
-                                    Logger.info "We don't go exchange"
-                                    check_offers(without_task)
-                                {:go_exchange, pid, _task} ->
-                                    Logger.info "I'm busy"
-                                    send pid, :busy
-                                    itself.(itself)
-                                :busy ->
-                                    Logger.info "It's busy"
-                                    Process.sleep(100)
-                                    check_offers(task_data)
-                                msg ->
-                                    IO.puts "Ignored #{inspect msg}"
-                                    itself.(itself)
-                            after
-                                1_000 ->
-                                    check_offers(without_task)
-                            end
-                        end
-                wait_agreement.(wait_agreement)
+                GenFSM.send_event(t, {:go_exchange, self(), without_task})
+                {:next_state, :wait_agreement, without_task,
+                 @wait_agreement_timeout}
             else
                 try_exchange(without_task)
             end
         end
     end
 
-    def check_offers task_data do
+    def wait_agreement(:no, without_task) do
+        Logger.info "We don't go exchange"
+        {:next_state, :check_offers, without_task, @check_offers_timeout}
+    end
+
+    def wait_agreement(:timeout, without_task) do
+        {:next_state, :check_offers, without_task, @check_offers_timeout}
+    end
+
+    def wait_agreement({:go, from, new_data}, _) do
+        Logger.info "go exchenge (is's agrement)!"
+        GenFSM.send_event(from, :done)
+        {:next_state, :check_offers, new_data,
+        @check_offers_timeout}
+    end
+
+    def wait_agreement({:go_exchange, from, _task}, without_task) do
+        Logger.info "I'm busy"
+        GenFSM.send_event(from, {:busy, self()})
+        {:next_state,
+        :wait_agreement, without_task,
+        @wait_agreement_timeout}
+    end
+
+    def wait_agreement({:busy, from}, without_task) do
+        Logger.info "It's busy"
+        Process.sleep(100)
+        task_data = without_task
+                 |> Tasks.push_remaining_tasks([from])
+        {:next_state, :check_offers,
+        task_data, @check_offers_timeout}
+    end
+
+    def check_offers({:go_exchange, from, other_data}, task_data) do
         Logger.info "check_offers"
-        receive do
-            {:go_exchange, pid, other_data} ->
-                Logger.info "Received offer "
-                         <> "(#{List.first task_data.employers} and"
-                         <> " #{List.first other_data.employers})."
-                if should_exchange?(task_data, other_data) do
-                    Logger.info "We should exchange"
-                    {new, oth_new} = Tasks.exchange(task_data, other_data)
-                    send pid, {:go, self(), oth_new}
-                    receive do
-                        :done ->
-                            Logger.info "Exchange finished."
-                            try_exchange(new)
-                        {:go_exchange, pid, _data} ->
-                            send pid, :busy
-                         msg ->
-                             IO.puts "Ignored #{inspect msg}"
-
-                    after 1_000 ->
-                            Logger.info "Exchange timeout."
-                            try_exchange(task_data)
-                    end
-                else
-                    Logger.info "We shouldn't exchange"
-                    send pid, :no
-                    try_exchange(task_data)
-                end
-            msg ->
-                IO.puts "Ignored #{inspect msg}"
-
-        after 1_000 -> try_exchange(task_data)
-        end
-    end
-
-    def check_offers_finally task_data do
-        receive do
-            {:go_exchange, pid, other_data} ->
-                Logger.info "Received offer "
-                         <> "(#{List.first task_data.employers} and"
-                         <> " #{List.first other_data.employers})."
-                if should_exchange?(task_data, other_data) do
-                    {new, oth_new} = Tasks.exchange(task_data, other_data)
-                    send pid, {:go, self(), oth_new}
-                    receive do
-                        :done ->
-                            Logger.info "Exchange finished."
-                            check_offers_finally(new)
-                    after 1_000 ->
-                            Logger.info "Exchange timeout."
-                            check_offers_finally(task_data)
-                    end
-                else
-                    send pid, :no
-                    check_offers_finally(task_data)
-                end
-        after 2_000 ->
-            job_is_done task_data
-        end
+        Logger.info "Received offer "
+                 <> "(#{List.first task_data.employers} and"
+                 <> " #{List.first other_data.employers})."
+        if should_exchange?(task_data, other_data) do
+            Logger.info "We should exchange"
+            {new, oth_new} = Tasks.exchange(task_data, other_data)
+            GenFSM.send_event(from, {:go, self(), oth_new})
+            {:next_state,
+             :make_offer, {task_data, new},
+             @make_offer_timeout}
+        else
+            Logger.info "We shouldn't exchange"
+            GenFSM.send_event(from, :no)
+            try_exchange(task_data)
+        end
+    end
+
+    def check_offers(:timeout, task_data), do: try_exchange(task_data)
+
+    def check_offers(msg, task_data) do
+        IO.puts "Ignored #{inspect msg}"
+        {:next_state, :check_offers, task_data, @check_offers_timeout}
+    end
+
+    def make_offer(:done, {_, new}) do
+        Logger.info "Exchange finished."
+        try_exchange(new)
+    end
+
+    def make_offer(:timeout,  {task_data, _}) do
+        # Maybe wrong
+        try_exchange(task_data)
+    end
+
+    def make_offer({:go_exchange, from, _data}, {task_data, new}) do
+        # We shouldn't update timer
+        GenFSM.send_event(from, :busy)
+        {:next_state,
+         :make_offer, {task_data, new}
+        }
+    end
+
+    def make_offer msg, {task_data, new} do
+        IO.puts "Ignored #{inspect msg}"
+        # We shouldn't update timer
+        {:next_state,
+         :make_offer, {task_data, new},
+        }
+    end
+
+    def check_offers_finally({:go_exchange, from, other_data}, task_data) do
+        Logger.info "Received offer "
+                 <> "(#{List.first task_data.employers} and"
+                 <> " #{List.first other_data.employers})."
+        if should_exchange?(task_data, other_data) do
+            {new, oth_new} = Tasks.exchange(task_data, other_data)
+            GenFSM.send_event(from, {:go, self(), oth_new})
+            {:next_state,
+             :make_offer_finally,
+             {task_data, new},
+             @check_offers_timeout}
+        else
+            GenFSM.send_event(from, :no)
+            {:next_state,
+             :check_offers_finally, task_data,
+             @check_offers_finally_timeout}
+        end
+    end
+
+    def check_offers_finally :timeout, task_data do
+        job_is_done(task_data)
+    end
+
+    def make_offer_finally :done, {_, new_data} do
+        Logger.info "Exchange finished."
+        {:next_state, :check_offers_finally,
+        new_data, @check_offers_finally_timeout}
+    end
+
+    def make_offer_finally :timeout, {old, _} do
+        Logger.info "Exchange timeout."
+        {:next_state, :check_offers_finally,
+        old, @check_offers_finally_timeout}
+    end
+
+    def make_offer_finally msg, {old, new} do
+        Logger.info "Ignored: #{inspect msg}"
+        # We shouldn't update timer
+        {:next_state,
+        :make_offer_finally, {old, new}}
+    end
+
+    def handle_info info, statename, state do
+        IO.puts "HANDLE_INFO"
+        IO.inspect(info)
+        IO.inspect(statename)
+        {:stop, :terminate, state}
     end
 
     def job_is_done task_data do

        Logger.info "I'm DONE."
                 <> "List of empls: #{inspect task_data.employers}\n"
                 <> "Task: #{task_data.task} (#{coef})"
    end

    def should_exchange? first, second do
        {first_new, second_new} = Tasks.exchange(first, second)

        old_disbalance = [first, second]

        new_disbalance < old_disbalance
    end

    defp load_data filename do
        {:ok, list} = filename |> File.read! |> JSON.decode
        parse_data list
    end

    defp parse_data kw do
        %TaskSpec{
            employers: kw["employers"],
            task:      kw["task"]
