Update basic_waitable_timer to proposed interface.
diff --git a/asio/include/asio/basic_deadline_timer.hpp b/asio/include/asio/basic_deadline_timer.hpp
index 6aef75c..8115bb7 100644
--- a/asio/include/asio/basic_deadline_timer.hpp
+++ b/asio/include/asio/basic_deadline_timer.hpp
@@ -164,7 +164,7 @@
     : basic_io_object<TimerService>(io_service)
   {
     asio::error_code ec;
-    this->service.expires_at(this->implementation, expiry_time, ec);
+    this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
     asio::detail::throw_error(ec, "expires_at");
   }
 
@@ -183,7 +183,8 @@
     : basic_io_object<TimerService>(io_service)
   {
     asio::error_code ec;
-    this->service.expires_from_now(this->implementation, expiry_time, ec);
+    this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
     asio::detail::throw_error(ec, "expires_from_now");
   }
 
@@ -212,7 +213,7 @@
   std::size_t cancel()
   {
     asio::error_code ec;
-    std::size_t s = this->service.cancel(this->implementation, ec);
+    std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
     asio::detail::throw_error(ec, "cancel");
     return s;
   }
@@ -241,7 +242,7 @@
    */
   std::size_t cancel(asio::error_code& ec)
   {
-    return this->service.cancel(this->implementation, ec);
+    return this->get_service().cancel(this->get_implementation(), ec);
   }
 
   /// Cancels one asynchronous operation that is waiting on the timer.
@@ -271,7 +272,8 @@
   std::size_t cancel_one()
   {
     asio::error_code ec;
-    std::size_t s = this->service.cancel_one(this->implementation, ec);
+    std::size_t s = this->get_service().cancel_one(
+        this->get_implementation(), ec);
     asio::detail::throw_error(ec, "cancel_one");
     return s;
   }
@@ -302,7 +304,7 @@
    */
   std::size_t cancel_one(asio::error_code& ec)
   {
-    return this->service.cancel_one(this->implementation, ec);
+    return this->get_service().cancel_one(this->get_implementation(), ec);
   }
 
   /// Get the timer's expiry time as an absolute time.
@@ -312,7 +314,7 @@
    */
   time_type expires_at() const
   {
-    return this->service.expires_at(this->implementation);
+    return this->get_service().expires_at(this->get_implementation());
   }
 
   /// Set the timer's expiry time as an absolute time.
@@ -340,8 +342,8 @@
   std::size_t expires_at(const time_type& expiry_time)
   {
     asio::error_code ec;
-    std::size_t s = this->service.expires_at(
-        this->implementation, expiry_time, ec);
+    std::size_t s = this->get_service().expires_at(
+        this->get_implementation(), expiry_time, ec);
     asio::detail::throw_error(ec, "expires_at");
     return s;
   }
@@ -371,7 +373,8 @@
   std::size_t expires_at(const time_type& expiry_time,
       asio::error_code& ec)
   {
-    return this->service.expires_at(this->implementation, expiry_time, ec);
+    return this->get_service().expires_at(
+        this->get_implementation(), expiry_time, ec);
   }
 
   /// Get the timer's expiry time relative to now.
@@ -381,7 +384,7 @@
    */
   duration_type expires_from_now() const
   {
-    return this->service.expires_from_now(this->implementation);
+    return this->get_service().expires_from_now(this->get_implementation());
   }
 
   /// Set the timer's expiry time relative to now.
@@ -409,8 +412,8 @@
   std::size_t expires_from_now(const duration_type& expiry_time)
   {
     asio::error_code ec;
-    std::size_t s = this->service.expires_from_now(
-        this->implementation, expiry_time, ec);
+    std::size_t s = this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
     asio::detail::throw_error(ec, "expires_from_now");
     return s;
   }
@@ -440,8 +443,8 @@
   std::size_t expires_from_now(const duration_type& expiry_time,
       asio::error_code& ec)
   {
-    return this->service.expires_from_now(
-        this->implementation, expiry_time, ec);
+    return this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
   }
 
   /// Perform a blocking wait on the timer.
@@ -454,7 +457,7 @@
   void wait()
   {
     asio::error_code ec;
-    this->service.wait(this->implementation, ec);
+    this->get_service().wait(this->get_implementation(), ec);
     asio::detail::throw_error(ec, "wait");
   }
 
@@ -467,7 +470,7 @@
    */
   void wait(asio::error_code& ec)
   {
-    this->service.wait(this->implementation, ec);
+    this->get_service().wait(this->get_implementation(), ec);
   }
 
   /// Start an asynchronous wait on the timer.
@@ -503,7 +506,7 @@
     // not meet the documented type requirements for a WaitHandler.
     ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
 
-    return this->service.async_wait(this->implementation,
+    return this->get_service().async_wait(this->get_implementation(),
         ASIO_MOVE_CAST(WaitHandler)(handler));
   }
 };
diff --git a/asio/include/asio/basic_waitable_timer.hpp b/asio/include/asio/basic_waitable_timer.hpp
index 9b3f860..0fbe49b 100644
--- a/asio/include/asio/basic_waitable_timer.hpp
+++ b/asio/include/asio/basic_waitable_timer.hpp
@@ -54,7 +54,7 @@
  * asio::steady_timer timer(io_service);
  *
  * // Set an expiry time relative to now.
- * timer.expires_from_now(std::chrono::seconds(5));
+ * timer.expires_after(std::chrono::seconds(5));
  *
  * // Wait for the timer to expire.
  * timer.wait();
@@ -91,7 +91,7 @@
  * @code
  * void on_some_event()
  * {
- *   if (my_timer.expires_from_now(seconds(5)) > 0)
+ *   if (my_timer.expires_after(seconds(5)) > 0)
  *   {
  *     // We managed to cancel the timer. Start new asynchronous wait.
  *     my_timer.async_wait(on_timeout);
@@ -111,7 +111,7 @@
  * }
  * @endcode
  *
- * @li The asio::basic_waitable_timer::expires_from_now() function
+ * @li The asio::basic_waitable_timer::expires_after() function
  * cancels any pending asynchronous waits, and returns the number of
  * asynchronous waits that were cancelled. If it returns 0 then you were too
  * late and the wait handler has already been executed, or will soon be
@@ -127,6 +127,9 @@
   : public basic_io_object<WaitableTimerService>
 {
 public:
+  /// The executor type.
+  typedef asio::io_service::executor_type executor_type;
+
   /// The clock type.
   typedef Clock clock_type;
 
@@ -142,8 +145,8 @@
   /// Constructor.
   /**
    * This constructor creates a timer without setting an expiry time. The
-   * expires_at() or expires_from_now() functions must be called to set an
-   * expiry time before the timer can be waited on.
+   * expires_at() or expires_after() functions must be called to set an expiry
+   * time before the timer can be waited on.
    *
    * @param io_service The io_service object that the timer will use to dispatch
    * handlers for any asynchronous operations performed on the timer.
@@ -187,11 +190,46 @@
     : basic_io_object<WaitableTimerService>(io_service)
   {
     asio::error_code ec;
-    this->get_service().expires_from_now(
+    this->get_service().expires_after(
         this->get_implementation(), expiry_time, ec);
-    asio::detail::throw_error(ec, "expires_from_now");
+    asio::detail::throw_error(ec, "expires_after");
   }
 
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_waitable_timer from another.
+  /**
+   * This constructor moves a timer from one object to another.
+   *
+   * @param other The other basic_waitable_timer object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_waitable_timer(io_service&) constructor.
+   */
+  basic_waitable_timer(basic_waitable_timer&& other)
+    : basic_io_object<WaitableTimerService>(
+        ASIO_MOVE_CAST(basic_waitable_timer)(other))
+  {
+  }
+
+  /// Move-assign a basic_waitable_timer from another.
+  /**
+   * This assignment operator moves a timer from one object to another.
+   *
+   * @param other The other basic_waitable_timer object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_waitable_timer(io_service&) constructor.
+   */
+  basic_waitable_timer& operator=(basic_waitable_timer&& other)
+  {
+    basic_io_object<WaitableTimerService>::operator=(
+        ASIO_MOVE_CAST(basic_waitable_timer)(other));
+    return *this;
+  }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
   /// Cancel any asynchronous operations that are waiting on the timer.
   /**
    * This function forces the completion of any pending asynchronous wait
@@ -311,7 +349,9 @@
     return this->get_service().cancel_one(this->get_implementation(), ec);
   }
 
-  /// Get the timer's expiry time as an absolute time.
+#if defined(ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
+  /// time.
   /**
    * This function may be used to obtain the timer's current expiry time.
    * Whether the timer has expired or not does not affect this value.
@@ -320,6 +360,17 @@
   {
     return this->get_service().expires_at(this->get_implementation());
   }
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+  /// Get the timer's expiry time as an absolute time.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  time_point expiry() const
+  {
+    return this->get_service().expiry(this->get_implementation());
+  }
 
   /// Set the timer's expiry time as an absolute time.
   /**
@@ -381,7 +432,68 @@
         this->get_implementation(), expiry_time, ec);
   }
 
-  /// Get the timer's expiry time relative to now.
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_after() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_after(const duration& expiry_time)
+  {
+    asio::error_code ec;
+    std::size_t s = this->get_service().expires_after(
+        this->get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_after");
+    return s;
+  }
+
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_after() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_after(const duration& expiry_time,
+      asio::error_code& ec)
+  {
+    return this->get_service().expires_after(
+        this->get_implementation(), expiry_time, ec);
+  }
+
+#if !defined(ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now.
   /**
    * This function may be used to obtain the timer's current expiry time.
    * Whether the timer has expired or not does not affect this value.
@@ -391,7 +503,8 @@
     return this->get_service().expires_from_now(this->get_implementation());
   }
 
-  /// Set the timer's expiry time relative to now.
+  /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
+  /// to now.
   /**
    * This function sets the expiry time. Any pending asynchronous wait
    * operations will be cancelled. The handler for each cancelled operation will
@@ -422,7 +535,8 @@
     return s;
   }
 
-  /// Set the timer's expiry time relative to now.
+  /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
+  /// to now.
   /**
    * This function sets the expiry time. Any pending asynchronous wait
    * operations will be cancelled. The handler for each cancelled operation will
@@ -450,6 +564,7 @@
     return this->get_service().expires_from_now(
         this->get_implementation(), expiry_time, ec);
   }
+#endif // !defined(ASIO_NO_DEPRECATED)
 
   /// Perform a blocking wait on the timer.
   /**
diff --git a/asio/include/asio/deadline_timer_service.hpp b/asio/include/asio/deadline_timer_service.hpp
index b4d5aea..2efe935 100644
--- a/asio/include/asio/deadline_timer_service.hpp
+++ b/asio/include/asio/deadline_timer_service.hpp
@@ -105,7 +105,7 @@
   /// Get the expiry time for the timer as an absolute time.
   time_type expires_at(const implementation_type& impl) const
   {
-    return service_impl_.expires_at(impl);
+    return service_impl_.expiry(impl);
   }
 
   /// Set the expiry time for the timer as an absolute time.
@@ -118,14 +118,14 @@
   /// Get the expiry time for the timer relative to now.
   duration_type expires_from_now(const implementation_type& impl) const
   {
-    return service_impl_.expires_from_now(impl);
+    return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now());
   }
 
   /// Set the expiry time for the timer relative to now.
   std::size_t expires_from_now(implementation_type& impl,
       const duration_type& expiry_time, asio::error_code& ec)
   {
-    return service_impl_.expires_from_now(impl, expiry_time, ec);
+    return service_impl_.expires_after(impl, expiry_time, ec);
   }
 
   // Perform a blocking wait on the timer.
diff --git a/asio/include/asio/detail/deadline_timer_service.hpp b/asio/include/asio/detail/deadline_timer_service.hpp
index 50dee9e..3d4aebb 100644
--- a/asio/include/asio/detail/deadline_timer_service.hpp
+++ b/asio/include/asio/detail/deadline_timer_service.hpp
@@ -93,6 +93,38 @@
     cancel(impl, ec);
   }
 
+  // Move-construct a new serial port implementation.
+  void move_construct(implementation_type& impl,
+      implementation_type& other_impl)
+  {
+    scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data);
+
+    impl.expiry = other_impl.expiry;
+    other_impl.expiry = time_type();
+
+    impl.might_have_pending_waits = other_impl.might_have_pending_waits;
+    other_impl.might_have_pending_waits = false;
+  }
+
+  // Move-assign from another serial port implementation.
+  void move_assign(implementation_type& impl,
+      deadline_timer_service& other_service,
+      implementation_type& other_impl)
+  {
+    if (this != &other_service)
+      if (impl.might_have_pending_waits)
+        scheduler_.cancel_timer(timer_queue_, impl.timer_data);
+
+    other_service.scheduler_.move_timer(other_service.timer_queue_,
+        impl.timer_data, other_impl.timer_data);
+
+    impl.expiry = other_impl.expiry;
+    other_impl.expiry = time_type();
+
+    impl.might_have_pending_waits = other_impl.might_have_pending_waits;
+    other_impl.might_have_pending_waits = false;
+  }
+
   // Cancel any asynchronous wait operations associated with the timer.
   std::size_t cancel(implementation_type& impl, asio::error_code& ec)
   {
@@ -131,7 +163,7 @@
   }
 
   // Get the expiry time for the timer as an absolute time.
-  time_type expires_at(const implementation_type& impl) const
+  time_type expiry(const implementation_type& impl) const
   {
     return impl.expiry;
   }
@@ -146,14 +178,8 @@
     return count;
   }
 
-  // Get the expiry time for the timer relative to now.
-  duration_type expires_from_now(const implementation_type& impl) const
-  {
-    return Time_Traits::subtract(expires_at(impl), Time_Traits::now());
-  }
-
   // Set the expiry time for the timer relative to now.
-  std::size_t expires_from_now(implementation_type& impl,
+  std::size_t expires_after(implementation_type& impl,
       const duration_type& expiry_time, asio::error_code& ec)
   {
     return expires_at(impl,
diff --git a/asio/include/asio/detail/dev_poll_reactor.hpp b/asio/include/asio/detail/dev_poll_reactor.hpp
index a04463b..6ee4183 100644
--- a/asio/include/asio/detail/dev_poll_reactor.hpp
+++ b/asio/include/asio/detail/dev_poll_reactor.hpp
@@ -132,6 +132,12 @@
       typename timer_queue<Time_Traits>::per_timer_data& timer,
       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
 
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& to,
+      typename timer_queue<Time_Traits>::per_timer_data& from);
+
   // Run /dev/poll once until interrupted or events are ready to be dispatched.
   ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
diff --git a/asio/include/asio/detail/epoll_reactor.hpp b/asio/include/asio/detail/epoll_reactor.hpp
index 65da611..5993638 100644
--- a/asio/include/asio/detail/epoll_reactor.hpp
+++ b/asio/include/asio/detail/epoll_reactor.hpp
@@ -152,6 +152,12 @@
       typename timer_queue<Time_Traits>::per_timer_data& timer,
       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
 
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& to,
+      typename timer_queue<Time_Traits>::per_timer_data& from);
+
   // Run epoll once until interrupted or events are ready to be dispatched.
   ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
diff --git a/asio/include/asio/detail/impl/dev_poll_reactor.hpp b/asio/include/asio/detail/impl/dev_poll_reactor.hpp
index d929350..0fcf510 100644
--- a/asio/include/asio/detail/impl/dev_poll_reactor.hpp
+++ b/asio/include/asio/detail/impl/dev_poll_reactor.hpp
@@ -68,6 +68,19 @@
   return n;
 }
 
+template <typename Time_Traits>
+void dev_poll_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& to,
+    typename timer_queue<Time_Traits>::per_timer_data& from)
+{
+  asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(to, ops);
+  queue.move_timer(to, from);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/impl/epoll_reactor.hpp b/asio/include/asio/detail/impl/epoll_reactor.hpp
index 91d85d4..b854b53 100644
--- a/asio/include/asio/detail/impl/epoll_reactor.hpp
+++ b/asio/include/asio/detail/impl/epoll_reactor.hpp
@@ -66,6 +66,19 @@
   return n;
 }
 
+template <typename Time_Traits>
+void epoll_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& to,
+    typename timer_queue<Time_Traits>::per_timer_data& from)
+{
+  asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(to, ops);
+  queue.move_timer(to, from);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/impl/kqueue_reactor.hpp b/asio/include/asio/detail/impl/kqueue_reactor.hpp
index 0f70b0b..f87e862 100644
--- a/asio/include/asio/detail/impl/kqueue_reactor.hpp
+++ b/asio/include/asio/detail/impl/kqueue_reactor.hpp
@@ -70,6 +70,19 @@
   return n;
 }
 
+template <typename Time_Traits>
+void kqueue_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& to,
+    typename timer_queue<Time_Traits>::per_timer_data& from)
+{
+  asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(to, ops);
+  queue.move_timer(to, from);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/impl/select_reactor.hpp b/asio/include/asio/detail/impl/select_reactor.hpp
index 3ca2608..3591906 100644
--- a/asio/include/asio/detail/impl/select_reactor.hpp
+++ b/asio/include/asio/detail/impl/select_reactor.hpp
@@ -73,6 +73,19 @@
   return n;
 }
 
+template <typename Time_Traits>
+void select_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& to,
+    typename timer_queue<Time_Traits>::per_timer_data& from)
+{
+  asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(to, ops);
+  queue.move_timer(to, from);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/impl/win_iocp_io_service.hpp b/asio/include/asio/detail/impl/win_iocp_io_service.hpp
index df7ba80..37d6a7f 100644
--- a/asio/include/asio/detail/impl/win_iocp_io_service.hpp
+++ b/asio/include/asio/detail/impl/win_iocp_io_service.hpp
@@ -80,6 +80,19 @@
   return n;
 }
 
+template <typename Time_Traits>
+void win_iocp_io_service::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& to,
+    typename timer_queue<Time_Traits>::per_timer_data& from)
+{
+  asio::detail::mutex::scoped_lock lock(dispatch_mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(to, ops);
+  queue.move_timer(to, from);
+  lock.unlock();
+  post_deferred_completions(ops);
+}
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp b/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp
index 544758d..f76005a 100644
--- a/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp
+++ b/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp
@@ -69,6 +69,19 @@
   return n;
 }
 
+template <typename Time_Traits>
+void winrt_timer_scheduler::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& to,
+    typename timer_queue<Time_Traits>::per_timer_data& from)
+{
+  asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(to, ops);
+  queue.move_timer(to, from);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/kqueue_reactor.hpp b/asio/include/asio/detail/kqueue_reactor.hpp
index 194354d..8df24c1 100644
--- a/asio/include/asio/detail/kqueue_reactor.hpp
+++ b/asio/include/asio/detail/kqueue_reactor.hpp
@@ -155,6 +155,12 @@
       typename timer_queue<Time_Traits>::per_timer_data& timer,
       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
 
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& to,
+      typename timer_queue<Time_Traits>::per_timer_data& from);
+
   // Run the kqueue loop.
   ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
diff --git a/asio/include/asio/detail/select_reactor.hpp b/asio/include/asio/detail/select_reactor.hpp
index 2d67d81..c0a473f 100644
--- a/asio/include/asio/detail/select_reactor.hpp
+++ b/asio/include/asio/detail/select_reactor.hpp
@@ -141,6 +141,12 @@
       typename timer_queue<Time_Traits>::per_timer_data& timer,
       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
 
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& to,
+      typename timer_queue<Time_Traits>::per_timer_data& from);
+
   // Run select once until interrupted or events are ready to be dispatched.
   ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
diff --git a/asio/include/asio/detail/timer_queue.hpp b/asio/include/asio/detail/timer_queue.hpp
index 171619c..df85c07 100644
--- a/asio/include/asio/detail/timer_queue.hpp
+++ b/asio/include/asio/detail/timer_queue.hpp
@@ -46,7 +46,11 @@
   class per_timer_data
   {
   public:
-    per_timer_data() : next_(0), prev_(0) {}
+    per_timer_data() :
+      heap_index_((std::numeric_limits<std::size_t>::max)()),
+      next_(0), prev_(0)
+    {
+    }
 
   private:
     friend class timer_queue;
@@ -188,6 +192,29 @@
     return num_cancelled;
   }
 
+  // Move operations from one timer to another, empty timer.
+  void move_timer(per_timer_data& to, per_timer_data& from)
+  {
+    to.op_queue_.push(from.op_queue_);
+
+    to.heap_index_ = from.heap_index_;
+    from.heap_index_ = (std::numeric_limits<std::size_t>::max)();
+
+    if (to.heap_index_ < heap_.size())
+      heap_[to.heap_index_].timer_ = &to;
+
+    if (timers_ == &from)
+      timers_ = &to;
+    if (from.prev_)
+      from.prev_->next_ = &to;
+    if (from.next_)
+      from.next_->prev_= &to;
+    to.next_ = from.next_;
+    to.prev_ = from.prev_;
+    from.next_ = 0;
+    from.prev_ = 0;
+  }
+
 private:
   // Move the item at the given index up the heap to its correct position.
   void up_heap(std::size_t index)
diff --git a/asio/include/asio/detail/win_iocp_io_service.hpp b/asio/include/asio/detail/win_iocp_io_service.hpp
index ad6f92f..fbfbd32 100644
--- a/asio/include/asio/detail/win_iocp_io_service.hpp
+++ b/asio/include/asio/detail/win_iocp_io_service.hpp
@@ -191,6 +191,12 @@
       typename timer_queue<Time_Traits>::per_timer_data& timer,
       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
 
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& to,
+      typename timer_queue<Time_Traits>::per_timer_data& from);
+
 private:
 #if defined(WINVER) && (WINVER < 0x0500)
   typedef DWORD dword_ptr_t;
diff --git a/asio/include/asio/detail/winrt_timer_scheduler.hpp b/asio/include/asio/detail/winrt_timer_scheduler.hpp
index b4cbb63..459746f 100644
--- a/asio/include/asio/detail/winrt_timer_scheduler.hpp
+++ b/asio/include/asio/detail/winrt_timer_scheduler.hpp
@@ -81,6 +81,12 @@
       typename timer_queue<Time_Traits>::per_timer_data& timer,
       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
 
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& to,
+      typename timer_queue<Time_Traits>::per_timer_data& from);
+
 private:
   // Run the select loop in the thread.
   ASIO_DECL void run_thread();
diff --git a/asio/include/asio/ssl/detail/io.hpp b/asio/include/asio/ssl/detail/io.hpp
index c31b744..0916bea 100644
--- a/asio/include/asio/ssl/detail/io.hpp
+++ b/asio/include/asio/ssl/detail/io.hpp
@@ -148,7 +148,7 @@
           // cannot allow more than one read operation at a time on the
           // underlying transport. The pending_read_ timer's expiry is set to
           // pos_infin if a read is in progress, and neg_infin otherwise.
-          if (core_.pending_read_.expires_at() == core_.neg_infin())
+          if (core_.expiry(core_.pending_read_) == core_.neg_infin())
           {
             // Prevent other read operations from being started.
             core_.pending_read_.expires_at(core_.pos_infin());
@@ -175,7 +175,7 @@
           // cannot allow more than one write operation at a time on the
           // underlying transport. The pending_write_ timer's expiry is set to
           // pos_infin if a write is in progress, and neg_infin otherwise.
-          if (core_.pending_write_.expires_at() == core_.neg_infin())
+          if (core_.expiry(core_.pending_write_) == core_.neg_infin())
           {
             // Prevent other write operations from being started.
             core_.pending_write_.expires_at(core_.pos_infin());
diff --git a/asio/include/asio/ssl/detail/stream_core.hpp b/asio/include/asio/ssl/detail/stream_core.hpp
index cfce0ff..c45c78f 100644
--- a/asio/include/asio/ssl/detail/stream_core.hpp
+++ b/asio/include/asio/ssl/detail/stream_core.hpp
@@ -75,6 +75,13 @@
   {
     return boost::posix_time::pos_infin;
   }
+
+  // Helper function to get a timer's expiry time.
+  static asio::deadline_timer::time_type expiry(
+      const asio::deadline_timer& timer)
+  {
+    return timer.expires_at();
+  }
 #else // defined(ASIO_HAS_BOOST_DATE_TIME)
   // Timer used for storing queued read operations.
   asio::steady_timer pending_read_;
@@ -93,6 +100,13 @@
   {
     return (asio::steady_timer::time_point::max)();
   }
+
+  // Helper function to get a timer's expiry time.
+  static asio::steady_timer::time_point expiry(
+      const asio::steady_timer& timer)
+  {
+    return timer.expiry();
+  }
 #endif // defined(ASIO_HAS_BOOST_DATE_TIME)
 
   // Buffer space used to prepare output intended for the transport.
diff --git a/asio/include/asio/wait_traits.hpp b/asio/include/asio/wait_traits.hpp
index 3b2218f..dec13d5 100644
--- a/asio/include/asio/wait_traits.hpp
+++ b/asio/include/asio/wait_traits.hpp
@@ -24,7 +24,7 @@
 struct wait_traits
 {
   /// Convert a clock duration into a duration used for waiting.
-  /** 
+  /**
    * @returns @c d.
    */
   static typename Clock::duration to_wait_duration(
@@ -32,6 +32,21 @@
   {
     return d;
   }
+
+  /// Convert a clock duration into a duration used for waiting.
+  /**
+   * @returns @c d.
+   */
+  static typename Clock::duration to_wait_duration(
+      const typename Clock::time_point& t)
+  {
+    typename Clock::time_point now = Clock::now();
+    if (now + Clock::duration::max() < t)
+      return Clock::duration::max();
+    if (now + Clock::duration::min() > t)
+      return Clock::duration::min();
+    return t - now;
+  }
 };
 
 } // namespace asio
diff --git a/asio/include/asio/waitable_timer_service.hpp b/asio/include/asio/waitable_timer_service.hpp
index 3aac26c..8760af4 100644
--- a/asio/include/asio/waitable_timer_service.hpp
+++ b/asio/include/asio/waitable_timer_service.hpp
@@ -89,6 +89,23 @@
     service_impl_.destroy(impl);
   }
 
+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a new timer implementation.
+  void move_construct(implementation_type& impl,
+      implementation_type& other_impl)
+  {
+    service_impl_.move_construct(impl, other_impl);
+  }
+
+  /// Move-assign from another timer implementation.
+  void move_assign(implementation_type& impl,
+      waitable_timer_service& other_service,
+      implementation_type& other_impl)
+  {
+    service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
+  }
+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
   /// Cancel any asynchronous wait operations associated with the timer.
   std::size_t cancel(implementation_type& impl, asio::error_code& ec)
   {
@@ -102,10 +119,19 @@
     return service_impl_.cancel_one(impl, ec);
   }
 
-  /// Get the expiry time for the timer as an absolute time.
+#if !defined(ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the expiry time for the timer as an
+  /// absolute time.
   time_point expires_at(const implementation_type& impl) const
   {
-    return service_impl_.expires_at(impl);
+    return service_impl_.expiry(impl);
+  }
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+  /// Get the expiry time for the timer as an absolute time.
+  time_point expiry(const implementation_type& impl) const
+  {
+    return service_impl_.expiry(impl);
   }
 
   /// Set the expiry time for the timer as an absolute time.
@@ -115,18 +141,30 @@
     return service_impl_.expires_at(impl, expiry_time, ec);
   }
 
-  /// Get the expiry time for the timer relative to now.
-  duration expires_from_now(const implementation_type& impl) const
+  /// Set the expiry time for the timer relative to now.
+  std::size_t expires_after(implementation_type& impl,
+      const duration& expiry_time, asio::error_code& ec)
   {
-    return service_impl_.expires_from_now(impl);
+    return service_impl_.expires_after(impl, expiry_time, ec);
   }
 
-  /// Set the expiry time for the timer relative to now.
+#if !defined(ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the expiry time for the timer relative to
+  /// now.
+  duration expires_from_now(const implementation_type& impl) const
+  {
+    typedef detail::chrono_time_traits<Clock, WaitTraits> traits;
+    return traits::subtract(service_impl_.expiry(impl), traits::now());
+  }
+
+  /// (Deprecated: Use expires_after().) Set the expiry time for the timer
+  /// relative to now.
   std::size_t expires_from_now(implementation_type& impl,
       const duration& expiry_time, asio::error_code& ec)
   {
-    return service_impl_.expires_from_now(impl, expiry_time, ec);
+    return service_impl_.expires_after(impl, expiry_time, ec);
   }
+#endif // !defined(ASIO_NO_DEPRECATED)
 
   // Perform a blocking wait on the timer.
   void wait(implementation_type& impl, asio::error_code& ec)
diff --git a/asio/src/doc/requirements/WaitTraits.qbk b/asio/src/doc/requirements/WaitTraits.qbk
index 19aaed1..a77190e 100644
--- a/asio/src/doc/requirements/WaitTraits.qbk
+++ b/asio/src/doc/requirements/WaitTraits.qbk
@@ -8,8 +8,9 @@
 [section:WaitTraits Wait traits requirements]
 
 In the table below, `X` denotes a wait traits class for clock type `Clock`,
-where `Clock` meets the C++11 type requirements for a clock, and `d` denotes
-a value of type `Clock::duration`.
+where `Clock` meets the C++11 type requirements for a clock, `t` denotes a
+value of type `Clock::time_point`, and `d` denotes a value of type
+`Clock::duration`.
 
 [table WaitTraits requirements
   [[expression] [return type] [assertion/note\npre/post-condition]]
@@ -18,7 +19,15 @@
     [`Clock::duration`]
     [
       Returns the maximum duration to be used for an individual,
-      implementation-defined wait operation.
+      implementation-defined wait operation for the duration `d`.
+    ]
+  ]
+  [
+    [`X::to_wait_duration(t);`]
+    [`Clock::duration`]
+    [
+      Returns the maximum duration to be used for an individual,
+      implementation-defined wait operation until the time point `t`.
     ]
   ]
 ]
diff --git a/asio/src/doc/requirements/WaitableTimerService.qbk b/asio/src/doc/requirements/WaitableTimerService.qbk
index a8faf6c..51d0981 100644
--- a/asio/src/doc/requirements/WaitableTimerService.qbk
+++ b/asio/src/doc/requirements/WaitableTimerService.qbk
@@ -42,7 +42,7 @@
     ]
   ]
   [
-    [`a.expires_at(b);`]
+    [`a.expiry(b);`]
     [`Clock::time_point`]
     []
   ]
@@ -58,15 +58,8 @@
     ]
   ]
   [
-    [`a.expires_from_now(b);`]
-    [`Clock::duration`]
-    [
-      Returns a value equivalent to `a.expires_at(b) - Clock::now()`.
-    ]
-  ]
-  [
     [``
-      a.expires_from_now(b, d, e);
+      a.expires_after(b, d, e);
     ``]
     [`size_t`]
     [
diff --git a/asio/src/tests/unit/strand.cpp b/asio/src/tests/unit/strand.cpp
index 93fd02e..da2ed00 100644
--- a/asio/src/tests/unit/strand.cpp
+++ b/asio/src/tests/unit/strand.cpp
@@ -151,10 +151,18 @@
   timer timer1(ios, chronons::seconds(3));
   timer1.wait();
   ASIO_CHECK(count == 0);
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
   timer1.expires_at(timer1.expires_at() + chronons::seconds(2));
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+  timer1.expires_at(timer1.expiry() + chronons::seconds(2));
+#endif defined(ASIO_HAS_BOOST_DATE_TIME)
   timer1.wait();
   ASIO_CHECK(count == 1);
+#if defined(ASIO_HAS_BOOST_DATE_TIME)
   timer1.expires_at(timer1.expires_at() + chronons::seconds(2));
+#else // defined(ASIO_HAS_BOOST_DATE_TIME)
+  timer1.expires_at(timer1.expiry() + chronons::seconds(2));
+#endif defined(ASIO_HAS_BOOST_DATE_TIME)
   timer1.wait();
   ASIO_CHECK(count == 2);
 
diff --git a/asio/src/tests/unit/system_timer.cpp b/asio/src/tests/unit/system_timer.cpp
index 1d392c5..021ee33 100644
--- a/asio/src/tests/unit/system_timer.cpp
+++ b/asio/src/tests/unit/system_timer.cpp
@@ -55,7 +55,7 @@
 
     int before_value = *count;
 
-    t->expires_at(t->expires_at() + chronons::seconds(1));
+    t->expires_at(t->expiry() + chronons::seconds(1));
     t->async_wait(bindns::bind(decrement_to_zero, t, count));
 
     // Completion cannot nest, so count value should remain unchanged.
@@ -119,7 +119,7 @@
   expected_end = start + seconds(1) + microseconds(500000);
   ASIO_CHECK(expected_end < end || expected_end == end);
 
-  t2.expires_at(t2.expires_at() + seconds(1));
+  t2.expires_at(t2.expiry() + seconds(1));
   t2.wait();
 
   // The timer must block until after its expiry time.
@@ -129,7 +129,7 @@
 
   start = now();
 
-  t2.expires_from_now(seconds(1) + microseconds(200000));
+  t2.expires_after(seconds(1) + microseconds(200000));
   t2.wait();
 
   // The timer must block until after its expiry time.
@@ -327,13 +327,13 @@
 
   asio::thread th(bindns::bind(io_service_run, &ios));
 
-  t2.expires_from_now(chronons::seconds(2));
+  t2.expires_after(chronons::seconds(2));
   t2.wait();
 
-  t1.expires_from_now(chronons::seconds(2));
+  t1.expires_after(chronons::seconds(2));
   t1.async_wait(bindns::bind(increment, &count));
 
-  t2.expires_from_now(chronons::seconds(4));
+  t2.expires_after(chronons::seconds(4));
   t2.wait();
 
   ios.stop();
@@ -342,6 +342,39 @@
   ASIO_CHECK(count == 1);
 }
 
+#if defined(ASIO_HAS_MOVE)
+asio::system_timer make_timer(asio::io_service& ios, int* count)
+{
+  asio::system_timer t(ios);
+  t.expires_after(std::chrono::seconds(1));
+  t.async_wait(bindns::bind(increment, count));
+  return t;
+}
+#endif
+
+void system_timer_move_test()
+{
+#if defined(ASIO_HAS_MOVE)
+  asio::io_service io_service1;
+  asio::io_service io_service2;
+  int count = 0;
+
+  asio::system_timer t1 = make_timer(io_service1, &count);
+  asio::system_timer t2 = make_timer(io_service2, &count);
+  asio::system_timer t3 = std::move(t1);
+
+  t2 = std::move(t1);
+
+  io_service2.run();
+
+  ASIO_CHECK(count == 1);
+
+  io_service1.run();
+
+  ASIO_CHECK(count == 2);
+#endif // defined(ASIO_HAS_MOVE)
+}
+
 ASIO_TEST_SUITE
 (
   "system_timer",
@@ -349,6 +382,7 @@
   ASIO_TEST_CASE(system_timer_cancel_test)
   ASIO_TEST_CASE(system_timer_custom_allocation_test)
   ASIO_TEST_CASE(system_timer_thread_test)
+  ASIO_TEST_CASE(system_timer_move_test)
 )
 #else // defined(ASIO_HAS_STD_CHRONO)
 ASIO_TEST_SUITE