Finish implementation of move-enabled accept/async_accept.
diff --git a/asio/include/asio/basic_socket_acceptor.hpp b/asio/include/asio/basic_socket_acceptor.hpp
index 287652d..983dd5b 100644
--- a/asio/include/asio/basic_socket_acceptor.hpp
+++ b/asio/include/asio/basic_socket_acceptor.hpp
@@ -1308,8 +1308,7 @@
    *
    * asio::ip::tcp::acceptor acceptor(io_service);
    * ...
-   * asio::ip::tcp::socket socket(io_service);
-   * acceptor.async_accept(socket, accept_handler);
+   * acceptor.async_accept(accept_handler);
    * @endcode
    */
   template <typename MoveAcceptHandler>
@@ -1323,7 +1322,405 @@
         handler, typename Protocol::socket) type_check;
 
     return this->get_service().async_accept(this->get_implementation(),
-        static_cast<endpoint_type*>(0),
+        static_cast<asio::io_service*>(0), static_cast<endpoint_type*>(0),
+        ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_service The io_service object to be used for the newly accepted
+   * socket.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::socket socket(acceptor.accept());
+   * @endcode
+   */
+  typename Protocol::socket accept(asio::io_service& io_service)
+  {
+    asio::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(this->get_implementation(),
+          &io_service, static_cast<endpoint_type*>(0), ec));
+    asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_service The io_service object to be used for the newly accepted
+   * socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::socket socket(acceptor.accept(io_service2, ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(
+      asio::io_service& io_service, asio::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(),
+        &io_service, static_cast<endpoint_type*>(0), ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_service The io_service object to be used for the newly accepted
+   * socket.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * asio::io_service::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const asio::error_code& error,
+   *     asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * acceptor.async_accept(io_service2, accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (asio::error_code, typename Protocol::socket))
+  async_accept(asio::io_service& io_service,
+      ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+    return this->get_service().async_accept(this->get_implementation(),
+        &io_service, static_cast<endpoint_type*>(0),
+        ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::endpoint endpoint;
+   * asio::ip::tcp::socket socket(acceptor.accept(endpoint));
+   * @endcode
+   */
+  typename Protocol::socket accept(endpoint_type& peer_endpoint)
+  {
+    asio::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(this->get_implementation(),
+          static_cast<asio::io_service*>(0), &peer_endpoint, ec));
+    asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::endpoint endpoint;
+   * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(
+      endpoint_type& peer_endpoint, asio::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(),
+        static_cast<asio::io_service*>(0), &peer_endpoint, ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written. Ownership of the peer_endpoint object is
+   * retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * asio::io_service::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const asio::error_code& error,
+   *     asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::endpoint endpoint;
+   * acceptor.async_accept(endpoint, accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (asio::error_code, typename Protocol::socket))
+  async_accept(endpoint_type& peer_endpoint,
+      ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+    return this->get_service().async_accept(this->get_implementation(),
+        static_cast<asio::io_service*>(0), &peer_endpoint,
+        ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_service The io_service object to be used for the newly accepted
+   * socket.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::endpoint endpoint;
+   * asio::ip::tcp::socket socket(
+   *     acceptor.accept(io_service2, endpoint));
+   * @endcode
+   */
+  typename Protocol::socket accept(
+      asio::io_service& io_service, endpoint_type& peer_endpoint)
+  {
+    asio::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(this->get_implementation(),
+          &io_service, &peer_endpoint, ec));
+    asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_service The io_service object to be used for the newly accepted
+   * socket.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::endpoint endpoint;
+   * asio::ip::tcp::socket socket(
+   *     acceptor.accept(io_service2, endpoint, ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(asio::io_service& io_service,
+      endpoint_type& peer_endpoint, asio::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(),
+        &io_service, &peer_endpoint, ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_service The io_service object to be used for the newly accepted
+   * socket.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written. Ownership of the peer_endpoint object is
+   * retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const asio::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * asio::io_service::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const asio::error_code& error,
+   *     asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * asio::ip::tcp::acceptor acceptor(io_service);
+   * ...
+   * asio::ip::tcp::endpoint endpoint;
+   * acceptor.async_accept(io_service2, endpoint, accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (asio::error_code, typename Protocol::socket))
+  async_accept(asio::io_service& io_service,
+      endpoint_type& peer_endpoint,
+      ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+    return this->get_service().async_accept(
+        this->get_implementation(), &io_service, &peer_endpoint,
         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
   }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
diff --git a/asio/include/asio/detail/reactive_socket_accept_op.hpp b/asio/include/asio/detail/reactive_socket_accept_op.hpp
index ea83190..22620a6 100644
--- a/asio/include/asio/detail/reactive_socket_accept_op.hpp
+++ b/asio/include/asio/detail/reactive_socket_accept_op.hpp
@@ -160,8 +160,6 @@
     reactive_socket_move_accept_op* o(
         static_cast<reactive_socket_move_accept_op*>(base));
     ptr p = { asio::detail::addressof(o->handler_), o, o };
-    typename Protocol::socket peer(
-        ASIO_MOVE_CAST(typename Protocol::socket)(*o));
     handler_work<Handler> w(o->handler_);
 
     ASIO_HANDLER_COMPLETION((o));
@@ -172,9 +170,10 @@
     // with the handler. Consequently, a local copy of the handler is required
     // to ensure that any owning sub-object remains valid until after we have
     // deallocated the memory here.
-    detail::move_binder2<Handler, asio::error_code, typename Protocol::socket>
-      handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,
-        ASIO_MOVE_CAST(typename Protocol::socket)(peer));
+    detail::move_binder2<Handler,
+      asio::error_code, typename Protocol::socket>
+        handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,
+          ASIO_MOVE_CAST(typename Protocol::socket)(*o));
     p.h = asio::detail::addressof(handler.handler_);
     p.reset();
 
diff --git a/asio/include/asio/detail/reactive_socket_service.hpp b/asio/include/asio/detail/reactive_socket_service.hpp
index 4d3c723..432921b 100644
--- a/asio/include/asio/detail/reactive_socket_service.hpp
+++ b/asio/include/asio/detail/reactive_socket_service.hpp
@@ -388,6 +388,7 @@
     return ec;
   }
 
+#if defined(ASIO_HAS_MOVE)
   // Accept a new connection.
   typename Protocol::socket accept(implementation_type& impl,
       io_service* peer_io_service, endpoint_type* peer_endpoint,
@@ -412,6 +413,7 @@
 
     return peer;
   }
+#endif // defined(ASIO_HAS_MOVE)
 
   // Start an asynchronous accept. The peer and peer_endpoint objects must be
   // valid until the accept's handler is invoked.
@@ -440,6 +442,7 @@
   // the accept's handler is invoked.
   template <typename Handler>
   void async_accept(implementation_type& impl,
+      asio::io_service* peer_io_service,
       endpoint_type* peer_endpoint, Handler& handler)
   {
     bool is_continuation =
@@ -449,8 +452,8 @@
     typedef reactive_socket_move_accept_op<Protocol, Handler> op;
     typename op::ptr p = { asio::detail::addressof(handler),
       op::ptr::allocate(handler), 0 };
-    p.p = new (p.v) op(io_service_, impl.socket_, impl.state_,
-        impl.protocol_, peer_endpoint, handler);
+    p.p = new (p.v) op(peer_io_service ? *peer_io_service : io_service_,
+        impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler);
 
     ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept"));
 
diff --git a/asio/include/asio/detail/win_iocp_socket_accept_op.hpp b/asio/include/asio/detail/win_iocp_socket_accept_op.hpp
index d14c617..b6e4515 100644
--- a/asio/include/asio/detail/win_iocp_socket_accept_op.hpp
+++ b/asio/include/asio/detail/win_iocp_socket_accept_op.hpp
@@ -157,6 +157,136 @@
   Handler handler_;
 };
 
+#if defined(ASIO_HAS_MOVE)
+
+template <typename Protocol, typename Handler>
+class win_iocp_socket_move_accept_op : public operation
+{
+public:
+  ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_move_accept_op);
+
+  win_iocp_socket_move_accept_op(
+      win_iocp_socket_service_base& socket_service, socket_type socket,
+      const Protocol& protocol, asio::io_service& peer_io_service,
+      typename Protocol::endpoint* peer_endpoint,
+      bool enable_connection_aborted, Handler& handler)
+    : operation(&win_iocp_socket_move_accept_op::do_complete),
+      socket_service_(socket_service),
+      socket_(socket),
+      peer_(peer_io_service),
+      protocol_(protocol),
+      peer_endpoint_(peer_endpoint),
+      enable_connection_aborted_(enable_connection_aborted),
+      handler_(ASIO_MOVE_CAST(Handler)(handler))
+  {
+    handler_work<Handler>::start(handler_);
+  }
+
+  socket_holder& new_socket()
+  {
+    return new_socket_;
+  }
+
+  void* output_buffer()
+  {
+    return output_buffer_;
+  }
+
+  DWORD address_length()
+  {
+    return sizeof(sockaddr_storage_type) + 16;
+  }
+
+  static void do_complete(void* owner, operation* base,
+      const asio::error_code& result_ec,
+      std::size_t /*bytes_transferred*/)
+  {
+    asio::error_code ec(result_ec);
+
+    // Take ownership of the operation object.
+    win_iocp_socket_move_accept_op* o(
+        static_cast<win_iocp_socket_move_accept_op*>(base));
+    ptr p = { asio::detail::addressof(o->handler_), o, o };
+    handler_work<Handler> w(o->handler_);
+
+    if (owner)
+    {
+      typename Protocol::endpoint peer_endpoint;
+      std::size_t addr_len = peer_endpoint.capacity();
+      socket_ops::complete_iocp_accept(o->socket_,
+          o->output_buffer(), o->address_length(),
+          peer_endpoint.data(), &addr_len,
+          o->new_socket_.get(), ec);
+
+      // Restart the accept operation if we got the connection_aborted error
+      // and the enable_connection_aborted socket option is not set.
+      if (ec == asio::error::connection_aborted
+          && !o->enable_connection_aborted_)
+      {
+        o->reset();
+        o->socket_service_.restart_accept_op(o->socket_,
+            o->new_socket_, o->protocol_.family(),
+            o->protocol_.type(), o->protocol_.protocol(),
+            o->output_buffer(), o->address_length(), o);
+        p.v = p.p = 0;
+        return;
+      }
+
+      // If the socket was successfully accepted, transfer ownership of the
+      // socket to the peer object.
+      if (!ec)
+      {
+        o->peer_.assign(o->protocol_,
+            typename Protocol::socket::native_handle_type(
+              o->new_socket_.get(), peer_endpoint), ec);
+        if (!ec)
+          o->new_socket_.release();
+      }
+
+      // Pass endpoint back to caller.
+      if (o->peer_endpoint_)
+        *o->peer_endpoint_ = peer_endpoint;
+    }
+
+    ASIO_HANDLER_COMPLETION((o));
+
+    // Make a copy of the handler so that the memory can be deallocated before
+    // the upcall is made. Even if we're not about to make an upcall, a
+    // sub-object of the handler may be the true owner of the memory associated
+    // with the handler. Consequently, a local copy of the handler is required
+    // to ensure that any owning sub-object remains valid until after we have
+    // deallocated the memory here.
+    detail::move_binder2<Handler,
+      asio::error_code, typename Protocol::socket>
+        handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), ec,
+          ASIO_MOVE_CAST(typename Protocol::socket)(o->peer_));
+    p.h = asio::detail::addressof(handler.handler_);
+    p.reset();
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      fenced_block b(fenced_block::half);
+      ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
+      w.complete(handler, handler.handler_);
+      ASIO_HANDLER_INVOCATION_END;
+    }
+  }
+
+private:
+  win_iocp_socket_service_base& socket_service_;
+  socket_type socket_;
+  socket_holder new_socket_;
+  typename Protocol::socket peer_;
+  Protocol protocol_;
+  typename Protocol::endpoint* peer_endpoint_;
+  unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
+  bool enable_connection_aborted_;
+  Handler handler_;
+};
+
+#endif // defined(ASIO_HAS_MOVE)
+
 } // namespace detail
 } // namespace asio
 
diff --git a/asio/include/asio/detail/win_iocp_socket_service.hpp b/asio/include/asio/detail/win_iocp_socket_service.hpp
index 7903258..21f3e8d 100644
--- a/asio/include/asio/detail/win_iocp_socket_service.hpp
+++ b/asio/include/asio/detail/win_iocp_socket_service.hpp
@@ -457,13 +457,14 @@
     return ec;
   }
 
+#if defined(ASIO_HAS_MOVE)
   // Accept a new connection.
   typename Protocol::socket accept(implementation_type& impl,
       io_service* peer_io_service, endpoint_type* peer_endpoint,
       asio::error_code& ec)
   {
     typename Protocol::socket peer(
-        peer_io_service ? *peer_io_service : get_io_service());
+        peer_io_service ? *peer_io_service : io_service_);
 
     std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
     socket_holder new_socket(socket_ops::sync_accept(impl.socket_,
@@ -479,8 +480,9 @@
         new_socket.release();
     }
 
-    return ec;
+    return peer;
   }
+#endif // defined(ASIO_HAS_MOVE)
 
   // Start an asynchronous accept. The peer and peer_endpoint objects
   // must be valid until the accept's handler is invoked.
@@ -506,6 +508,34 @@
     p.v = p.p = 0;
   }
 
+#if defined(ASIO_HAS_MOVE)
+  // Start an asynchronous accept. The peer and peer_endpoint objects
+  // must be valid until the accept's handler is invoked.
+  template <typename Handler>
+  void async_accept(implementation_type& impl,
+      asio::io_service* peer_io_service,
+      endpoint_type* peer_endpoint, Handler& handler)
+  {
+    // Allocate and construct an operation to wrap the handler.
+    typedef win_iocp_socket_move_accept_op<protocol_type, Handler> op;
+    typename op::ptr p = { asio::detail::addressof(handler),
+      op::ptr::allocate(handler), 0 };
+    bool enable_connection_aborted =
+      (impl.state_ & socket_ops::enable_connection_aborted) != 0;
+    p.p = new (p.v) op(*this, impl.socket_, impl.protocol_,
+        peer_io_service ? *peer_io_service : io_service_,
+        peer_endpoint, enable_connection_aborted, handler);
+
+    ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept"));
+
+    start_accept_op(impl, false, p.p->new_socket(),
+        impl.protocol_.family(), impl.protocol_.type(),
+        impl.protocol_.protocol(), p.p->output_buffer(),
+        p.p->address_length(), p.p);
+    p.v = p.p = 0;
+  }
+#endif // defined(ASIO_HAS_MOVE)
+
   // Connect the socket to the specified endpoint.
   asio::error_code connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, asio::error_code& ec)
diff --git a/asio/include/asio/socket_acceptor_service.hpp b/asio/include/asio/socket_acceptor_service.hpp
index a1fe502..39d431c 100644
--- a/asio/include/asio/socket_acceptor_service.hpp
+++ b/asio/include/asio/socket_acceptor_service.hpp
@@ -310,13 +310,14 @@
   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
       void (asio::error_code, typename Protocol::socket))
   async_accept(implementation_type& impl,
-      endpoint_type* peer_endpoint,
+      asio::io_service* peer_io_service, endpoint_type* peer_endpoint,
       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
   {
     async_completion<MoveAcceptHandler,
       void (asio::error_code, typename Protocol::socket)> init(handler);
 
-    service_impl_.async_accept(impl, peer_endpoint, init.handler);
+    service_impl_.async_accept(impl,
+        peer_io_service, peer_endpoint, init.handler);
 
     return init.result.get();
   }
diff --git a/asio/src/examples/cpp11/allocation/server.cpp b/asio/src/examples/cpp11/allocation/server.cpp
index 35d4e9d..18f58b8 100644
--- a/asio/src/examples/cpp11/allocation/server.cpp
+++ b/asio/src/examples/cpp11/allocation/server.cpp
@@ -167,8 +167,7 @@
 {
 public:
   server(asio::io_service& io_service, short port)
-    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
-      socket_(io_service)
+    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
   {
     do_accept();
   }
@@ -176,12 +175,12 @@
 private:
   void do_accept()
   {
-    acceptor_.async_accept(socket_,
-        [this](std::error_code ec)
+    acceptor_.async_accept(
+        [this](std::error_code ec, tcp::socket socket)
         {
           if (!ec)
           {
-            std::make_shared<session>(std::move(socket_))->start();
+            std::make_shared<session>(std::move(socket))->start();
           }
 
           do_accept();
@@ -189,7 +188,6 @@
   }
 
   tcp::acceptor acceptor_;
-  tcp::socket socket_;
 };
 
 int main(int argc, char* argv[])
diff --git a/asio/src/examples/cpp11/buffers/reference_counted.cpp b/asio/src/examples/cpp11/buffers/reference_counted.cpp
index da66385..32c0d8a 100644
--- a/asio/src/examples/cpp11/buffers/reference_counted.cpp
+++ b/asio/src/examples/cpp11/buffers/reference_counted.cpp
@@ -73,8 +73,7 @@
 {
 public:
   server(asio::io_service& io_service, short port)
-    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
-      socket_(io_service)
+    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
   {
     do_accept();
   }
@@ -82,12 +81,12 @@
 private:
   void do_accept()
   {
-    acceptor_.async_accept(socket_,
-        [this](std::error_code ec)
+    acceptor_.async_accept(
+        [this](std::error_code ec, tcp::socket socket)
         {
           if (!ec)
           {
-            std::make_shared<session>(std::move(socket_))->start();
+            std::make_shared<session>(std::move(socket))->start();
           }
 
           do_accept();
@@ -95,7 +94,6 @@
   }
 
   tcp::acceptor acceptor_;
-  tcp::socket socket_;
 };
 
 int main(int argc, char* argv[])
diff --git a/asio/src/examples/cpp11/chat/chat_server.cpp b/asio/src/examples/cpp11/chat/chat_server.cpp
index 0fc20fb..d118576 100644
--- a/asio/src/examples/cpp11/chat/chat_server.cpp
+++ b/asio/src/examples/cpp11/chat/chat_server.cpp
@@ -171,8 +171,7 @@
 public:
   chat_server(asio::io_service& io_service,
       const tcp::endpoint& endpoint)
-    : acceptor_(io_service, endpoint),
-      socket_(io_service)
+    : acceptor_(io_service, endpoint)
   {
     do_accept();
   }
@@ -180,12 +179,12 @@
 private:
   void do_accept()
   {
-    acceptor_.async_accept(socket_,
-        [this](std::error_code ec)
+    acceptor_.async_accept(
+        [this](std::error_code ec, tcp::socket socket)
         {
           if (!ec)
           {
-            std::make_shared<chat_session>(std::move(socket_), room_)->start();
+            std::make_shared<chat_session>(std::move(socket), room_)->start();
           }
 
           do_accept();
@@ -193,7 +192,6 @@
   }
 
   tcp::acceptor acceptor_;
-  tcp::socket socket_;
   chat_room room_;
 };
 
diff --git a/asio/src/examples/cpp11/http/server/server.cpp b/asio/src/examples/cpp11/http/server/server.cpp
index 72b2e03..9114792 100644
--- a/asio/src/examples/cpp11/http/server/server.cpp
+++ b/asio/src/examples/cpp11/http/server/server.cpp
@@ -21,7 +21,6 @@
     signals_(io_service_),
     acceptor_(io_service_),
     connection_manager_(),
-    socket_(io_service_),
     request_handler_(doc_root)
 {
   // Register to handle the signals that indicate when the server should exit.
@@ -57,8 +56,8 @@
 
 void server::do_accept()
 {
-  acceptor_.async_accept(socket_,
-      [this](std::error_code ec)
+  acceptor_.async_accept(
+      [this](std::error_code ec, asio::ip::tcp::socket socket)
       {
         // Check whether the server was stopped by a signal before this
         // completion handler had a chance to run.
@@ -70,7 +69,7 @@
         if (!ec)
         {
           connection_manager_.start(std::make_shared<connection>(
-              std::move(socket_), connection_manager_, request_handler_));
+              std::move(socket), connection_manager_, request_handler_));
         }
 
         do_accept();
diff --git a/asio/src/examples/cpp11/http/server/server.hpp b/asio/src/examples/cpp11/http/server/server.hpp
index d82b5d3..88b8d75 100644
--- a/asio/src/examples/cpp11/http/server/server.hpp
+++ b/asio/src/examples/cpp11/http/server/server.hpp
@@ -54,9 +54,6 @@
   /// The connection manager which owns all live connections.
   connection_manager connection_manager_;
 
-  /// The next socket to be accepted.
-  asio::ip::tcp::socket socket_;
-
   /// The handler for all incoming requests.
   request_handler request_handler_;
 };
diff --git a/asio/src/tests/unit/ip/tcp.cpp b/asio/src/tests/unit/ip/tcp.cpp
index 1b0be8c..cc14f05 100644
--- a/asio/src/tests/unit/ip/tcp.cpp
+++ b/asio/src/tests/unit/ip/tcp.cpp
@@ -700,6 +700,17 @@
 #endif // defined(ASIO_HAS_MOVE)
 };
 
+#if defined(ASIO_HAS_MOVE)
+struct move_accept_handler
+{
+  move_accept_handler() {}
+  void operator()(const asio::error_code&, asio::ip::tcp::socket) {}
+  move_accept_handler(move_accept_handler&&) {}
+private:
+  move_accept_handler(const move_accept_handler&) {}
+};
+#endif // defined(ASIO_HAS_MOVE)
+
 void test()
 {
   using namespace asio;
@@ -822,12 +833,27 @@
     acceptor1.accept(peer_socket, peer_endpoint);
     acceptor1.accept(peer_socket, peer_endpoint, ec);
 
+#if defined(ASIO_HAS_MOVE)
+    peer_socket = acceptor1.accept();
+    peer_socket = acceptor1.accept(ios);
+    peer_socket = acceptor1.accept(peer_endpoint);
+    peer_socket = acceptor1.accept(ios, peer_endpoint);
+    (void)peer_socket;
+#endif // defined(ASIO_HAS_MOVE)
+
     acceptor1.async_accept(peer_socket, accept_handler());
     acceptor1.async_accept(peer_socket, peer_endpoint, accept_handler());
     int i2 = acceptor1.async_accept(peer_socket, lazy);
     (void)i2;
     int i3 = acceptor1.async_accept(peer_socket, peer_endpoint, lazy);
     (void)i3;
+
+#if defined(ASIO_HAS_MOVE)
+    acceptor1.async_accept(move_accept_handler());
+    acceptor1.async_accept(ios, move_accept_handler());
+    acceptor1.async_accept(peer_endpoint, move_accept_handler());
+    acceptor1.async_accept(ios, peer_endpoint, move_accept_handler());
+#endif // defined(ASIO_HAS_MOVE)
   }
   catch (std::exception&)
   {