void async_implementation::handle_timer(const boost::system::error_code& error)
{
  if (!has_do_something_handler())
  {
    return;
  }

  if (error)
  {
    std::cout << error_end_message_fmt_ % name_ % counter_;
    complete_do_something(error);
    return;
  }

  if (counter_)
  {
    --counter_;
    std::cout << cycle_message_fmt_ % name_ % counter_;

    boost::system::error_code timer_error;
    timer_.expires_from_now(
        to_steady_deadline_timer_duration(boost::posix_time::milliseconds(500)),
        timer_error);
    if (timer_error)
    {
      std::cout << error_end_message_fmt_ % name_ % counter_;
      complete_do_something(timer_error);
      return;
    }

#if defined(MA_HAS_RVALUE_REFS) && defined(MA_BIND_HAS_NO_MOVE_CONSTRUCTOR)

    timer_.async_wait(strand_.wrap(
        ma::make_custom_alloc_handler(timer_allocator_, timer_handler_binder(
            &this_type::handle_timer, shared_from_this()))));

#else

    timer_.async_wait(strand_.wrap(
        ma::make_custom_alloc_handler(timer_allocator_, detail::bind(
            &this_type::handle_timer, shared_from_this(),
            detail::placeholders::_1))));

#endif

    return;
  }

  // Continue work
  std::cout << success_end_message_fmt_ % name_ % counter_;
  complete_do_something(boost::system::error_code());
}
boost::optional<boost::system::error_code>
async_implementation::do_start_do_something()
{
  if (has_do_something_handler())
  {
    return boost::system::error_code(
        boost::asio::error::operation_not_supported);
  }

  counter_ = 10000;
  std::cout << start_message_fmt_ % name_ % counter_;

  boost::system::error_code timer_error;
  timer_.expires_from_now(
      to_steady_deadline_timer_duration(boost::posix_time::seconds(3)),
      timer_error);
  if (timer_error)
  {
    return timer_error;
  }

#if defined(MA_HAS_RVALUE_REFS) && defined(MA_BOOST_BIND_HAS_NO_MOVE_CONTRUCTOR)

  timer_.async_wait(MA_STRAND_WRAP(strand_, ma::make_custom_alloc_handler(
      timer_allocator_, timer_handler_binder(&this_type::handle_timer,
          shared_from_this()))));

#else

  timer_.async_wait(MA_STRAND_WRAP(strand_, ma::make_custom_alloc_handler(
      timer_allocator_, boost::bind(&this_type::handle_timer,
          shared_from_this(), _1))));

#endif

  return boost::optional<boost::system::error_code>();
}