Rename basic_stackless_context to stackless_context and make the
use of the template parameters explicit.
diff --git a/asio/include/asio/go.hpp b/asio/include/asio/go.hpp
index 1346964..c9d5fb5 100644
--- a/asio/include/asio/go.hpp
+++ b/asio/include/asio/go.hpp
@@ -18,7 +18,6 @@
 #include "asio/detail/config.hpp"
 #include "asio/coroutine.hpp"
 #include "asio/detail/variadic_templates.hpp"
-#include "asio/detail/wrapped_handler.hpp"
 #include "asio/io_service.hpp"
 #include "asio/strand.hpp"
 
@@ -49,12 +48,12 @@
 
 /// Context object the represents the currently executing coroutine.
 /**
- * The basic_stackless_context class is used to represent the currently
- * executing stackless coroutine. A basic_stackless_context may be passed as a
- * handler to an asynchronous operation. For example:
+ * The stackless_context class is used to represent the currently executing
+ * stackless coroutine. A stackless_context may be passed as a handler to an
+ * asynchronous operation. For example:
  *
  * @code template <typename Handler>
- * void my_coroutine(basic_stackless_context<Handler> ctx)
+ * void my_coroutine(stackless_context<Handler> ctx)
  * {
  *   reenter (ctx)
  *   {
@@ -68,8 +67,8 @@
  * the current coroutine. The coroutine is resumed when the asynchronous
  * operation completes.
  */
-template <typename Handler, typename Signature = void ()>
-class basic_stackless_context
+template <typename Handler = void, typename Signature = void ()>
+class stackless_context
 {
 public:
   /// Return a coroutine context that sets the specified error_code.
@@ -80,7 +79,7 @@
    * set with the asynchronous operation's result. For example:
    *
    * @code template <typename Handler>
-   * void my_coroutine(basic_stackless_context<Handler> ctx)
+   * void my_coroutine(stackless_context<Handler> ctx)
    * {
    *   reenter (ctx)
    *   {
@@ -94,9 +93,9 @@
    *   }
    * } @endcode
    */
-  basic_stackless_context operator[](asio::error_code& ec) const
+  stackless_context operator[](asio::error_code& ec) const
   {
-    basic_stackless_context tmp(*this);
+    stackless_context tmp(*this);
     tmp.ec_ = &ec;
     return tmp;
   }
@@ -106,10 +105,6 @@
    * This function is used to invoke the coroutine's associated completion
    * handler. It should be called at most once, immediately prior to the
    * termination of the coroutine. Additional calls will be ignored.
-   *
-   * For completion handlers with the signature <tt>void()</tt>, and if @c
-   * complete() is not explicitly called, the completion handler will be
-   * automatically invoked after coroutine termination.
    */
 #if defined(GENERATING_DOCUMENTATION) \
   || defined(ASIO_HAS_VARIADIC_TEMPLATES)
@@ -129,16 +124,6 @@
   asio::error_code* ec_;
 };
 
-#if defined(GENERATING_DOCUMENTATION)
-/// Context object that represents the currently executing coroutine.
-typedef basic_stackless_context<unspecified> stackless_context;
-#else // defined(GENERATING_DOCUMENTATION)
-typedef basic_stackless_context<
-  detail::wrapped_handler<
-    io_service::strand, void (*)(),
-    detail::is_continuation_if_running> > stackless_context;
-#endif // defined(GENERATING_DOCUMENTATION)
-
 /**
  * @defgroup go asio::go
  *
@@ -181,19 +166,28 @@
  */
 /*@{*/
 
+/// Start a new stackless coroutine.
+/**
+ * This function is used to launch a new coroutine.
+ *
+ * @param function The coroutine function. The function must have the signature:
+ * @code void function(stackless_context<void> c); @endcode
+ */
+template <typename Function>
+void go(ASIO_MOVE_ARG(Function) function);
+
 /// Start a new stackless coroutine with an associated completion handler.
 /**
  * This function is used to launch a new coroutine.
  *
  * @param handler The handler associated with the coroutine. The handler may be
- * explicitly called via the context's @c complete() function, but will be
- * invoked automatically after coroutine termination if not called first. More
+ * explicitly called via the context's @c complete() function. More
  * importantly, the handler provides an execution context (via the the handler
  * invocation hook) for the coroutine. The handler must have the signature:
  * @code void handler(); @endcode
  *
  * @param function The coroutine function. The function must have the signature:
- * @code void function(basic_stackless_context<Handler> c); @endcode
+ * @code void function(stackless_context<Handler> c); @endcode
  */
 template <typename Handler, typename Function>
 ASIO_INITFN_RESULT_TYPE(Handler, void ())
@@ -210,7 +204,7 @@
  * for the coroutine.
  *
  * @param function The coroutine function. The function must have the signature:
- * @code void function(basic_stackless_context<Handler, Signature> c); @endcode
+ * @code void function(stackless_context<Handler, Signature> c); @endcode
  */
 template <typename Signature, typename Handler, typename Function>
 ASIO_INITFN_RESULT_TYPE(Handler, Signature)
@@ -228,10 +222,10 @@
  * same strand.
  *
  * @param function The coroutine function. The function must have the signature:
- * @code void function(basic_stackless_context<Handler> yield); @endcode
+ * @code void function(stackless_context<Handler> yield); @endcode
  */
 template <typename Handler, typename Function>
-void go(basic_stackless_context<Handler> ctx,
+void go(stackless_context<Handler> ctx,
     ASIO_MOVE_ARG(Function) function);
 
 /// Start a new stackless coroutine that executes in the context of a strand.
@@ -243,7 +237,7 @@
  * execute simultaneously.
  *
  * @param function The coroutine function. The function must have the signature:
- * @code void function(stackless_context yield); @endcode
+ * @code void function(stackless_context<io_service::strand> yield); @endcode
  */
 template <typename Function>
 void go(asio::io_service::strand strand,
@@ -253,11 +247,10 @@
 /**
  * This function is used to launch a new coroutine.
  *
- * @param io_service Identifies the io_service that will run the coroutine. The
- * new coroutine is implicitly given its own strand within this io_service.
+ * @param io_service Identifies the io_service that will run the coroutine.
  *
  * @param function The coroutine function. The function must have the signature:
- * @code void function(stackless_context yield); @endcode
+ * @code void function(stackless_context<io_service> yield); @endcode
  */
 template <typename Function>
 void go(asio::io_service& io_service,
diff --git a/asio/include/asio/impl/go.hpp b/asio/include/asio/impl/go.hpp
index 824922e..ea84f63 100644
--- a/asio/include/asio/impl/go.hpp
+++ b/asio/include/asio/impl/go.hpp
@@ -22,6 +22,7 @@
 #include "asio/detail/handler_cont_helpers.hpp"
 #include "asio/detail/handler_invoke_helpers.hpp"
 #include "asio/detail/type_traits.hpp"
+#include "asio/detail/wrapped_handler.hpp"
 #include "asio/handler_type.hpp"
 
 #include "asio/detail/push_options.hpp"
@@ -30,12 +31,37 @@
 namespace detail {
 
   template <typename Handler, typename Signature>
+  struct stackless_handler_type
+  {
+    typedef typename handler_type<Handler, Signature>::type type;
+  };
+
+  template <>
+  struct stackless_handler_type<void, void()>
+  {
+    typedef void (*type)();
+  };
+
+  template <>
+  struct stackless_handler_type<asio::io_service, void()>
+  {
+    typedef wrapped_handler<asio::io_service&, void(*)()> type;
+  };
+
+  template <>
+  struct stackless_handler_type<asio::io_service::strand, void()>
+  {
+    typedef wrapped_handler<asio::io_service::strand,
+        void(*)(), is_continuation_if_running> type;
+  };
+
+  template <typename Handler, typename Signature>
   class stackless_impl_base
   {
   protected:
     template <typename Handler1>
     explicit stackless_impl_base(ASIO_MOVE_ARG(Handler1) handler,
-        void (*resume_fn)(const basic_stackless_context<Handler, Signature>&),
+        void (*resume_fn)(const stackless_context<Handler, Signature>&),
         void (*destroy_fn)(stackless_impl_base*))
       : handler_(ASIO_MOVE_CAST(Handler1)(handler)),
         ref_count_(1),
@@ -54,13 +80,13 @@
     static void resume(stackless_impl_base*& impl);
 
   //private:
-    typename handler_type<Handler, Signature>::type handler_;
+    typename stackless_handler_type<Handler, Signature>::type handler_;
     asio::detail::atomic_count ref_count_;
     asio::coroutine coroutine_;
     asio::error_code throw_ec_;
     asio::error_code* result_ec_;
     void* result_value_;
-    void (*resume_)(const basic_stackless_context<Handler, Signature>&);
+    void (*resume_)(const stackless_context<Handler, Signature>&);
     void (*destroy_)(stackless_impl_base*);
     bool completed_;
   };
@@ -96,34 +122,13 @@
     }
   }
 
-  template <typename Signature>
-  struct call_completed_handler
-  {
-    template <typename Handler>
-    static void call(Handler&) {}
-  };
-
-  template <>
-  struct call_completed_handler<void ()>
-  {
-    template <typename Handler>
-    static void call(Handler& h) { h(); }
-  };
-
   template <typename Handler, typename Signature>
   void stackless_impl_base<Handler, Signature>::resume(
       stackless_impl_base<Handler, Signature>*& impl)
   {
     impl->result_value_ = 0;
-    basic_stackless_context<Handler, Signature> ctx
-      = { &impl, &impl->throw_ec_ };
+    stackless_context<Handler, Signature> ctx = { &impl, &impl->throw_ec_ };
     impl->resume_(ctx);
-
-    if (impl && impl->coroutine_.is_complete() && !impl->completed_)
-    {
-      impl->completed_ = true;
-      call_completed_handler<Signature>::call(impl->handler_);
-    }
   }
 
   template <typename Handler, typename Signature, typename Function>
@@ -143,8 +148,7 @@
     }
 
   private:
-    static void do_resume(
-        const basic_stackless_context<Handler, Signature>& ctx)
+    static void do_resume(const stackless_context<Handler, Signature>& ctx)
     {
       stackless_impl_base<Handler, Signature>* base = *ctx.impl_;
       static_cast<stackless_impl*>(base)->function_(ctx);
@@ -162,7 +166,7 @@
   class stackless_handler
   {
   public:
-    stackless_handler(const basic_stackless_context<Handler, Signature>& ctx)
+    stackless_handler(const stackless_context<Handler, Signature>& ctx)
       : impl_(stackless_impl_base<Handler, Signature>::move_ref(*ctx.impl_))
     {
       impl_->result_ec_ = ctx.ec_;
@@ -212,7 +216,7 @@
   class stackless_handler<Handler, Signature, void>
   {
   public:
-    stackless_handler(const basic_stackless_context<Handler, Signature>& ctx)
+    stackless_handler(const stackless_context<Handler, Signature>& ctx)
       : impl_(stackless_impl_base<Handler, Signature>::move_ref(*ctx.impl_))
     {
       impl_->result_ec_ = ctx.ec_;
@@ -340,21 +344,20 @@
 #if !defined(GENERATING_DOCUMENTATION)
 
 template <typename Handler, typename Signature, typename ReturnType>
-struct handler_type<basic_stackless_context<Handler, Signature>, ReturnType()>
+struct handler_type<stackless_context<Handler, Signature>, ReturnType()>
 {
   typedef detail::stackless_handler<Handler, Signature, void> type;
 };
 
 template <typename Handler, typename Signature,
     typename ReturnType, typename Arg1>
-struct handler_type<basic_stackless_context<Handler, Signature>,
-    ReturnType(Arg1)>
+struct handler_type<stackless_context<Handler, Signature>, ReturnType(Arg1)>
 {
   typedef detail::stackless_handler<Handler, Signature, Arg1> type;
 };
 
 template <typename Handler, typename Signature, typename ReturnType>
-struct handler_type<basic_stackless_context<Handler, Signature>,
+struct handler_type<stackless_context<Handler, Signature>,
     ReturnType(asio::error_code)>
 {
   typedef detail::stackless_handler<Handler, Signature, void> type;
@@ -362,7 +365,7 @@
 
 template <typename Handler, typename Signature,
     typename ReturnType, typename Arg2>
-struct handler_type<basic_stackless_context<Handler, Signature>,
+struct handler_type<stackless_context<Handler, Signature>,
     ReturnType(asio::error_code, Arg2)>
 {
   typedef detail::stackless_handler<Handler, Signature, Arg2> type;
@@ -385,43 +388,41 @@
 };
 
 template <typename Handler, typename Signature>
-inline coroutine& get_coroutine(
-    basic_stackless_context<Handler, Signature>& c)
+inline coroutine& get_coroutine(stackless_context<Handler, Signature>& c)
 {
   return (*c.impl_)->coroutine_;
 }
 
 template <typename Handler, typename Signature>
-inline coroutine& get_coroutine(
-    basic_stackless_context<Handler, Signature>* c)
+inline coroutine& get_coroutine(stackless_context<Handler, Signature>* c)
 {
   return (*c->impl_)->coroutine_;
 }
 
 template <typename Handler, typename Signature>
 inline const asio::error_code* get_coroutine_error(
-    basic_stackless_context<Handler, Signature>& c)
+    stackless_context<Handler, Signature>& c)
 {
   return &(*c.impl_)->throw_ec_;
 }
 
 template <typename Handler, typename Signature>
 inline const asio::error_code* get_coroutine_error(
-    basic_stackless_context<Handler, Signature>* c)
+    stackless_context<Handler, Signature>* c)
 {
   return &(*c->impl_)->throw_ec_;
 }
 
 template <typename Handler, typename Signature>
 inline void** get_coroutine_async_result(
-    basic_stackless_context<Handler, Signature>& c)
+    stackless_context<Handler, Signature>& c)
 {
   return &(*c.impl_)->result_value_;
 }
 
 template <typename Handler, typename Signature>
 inline void** get_coroutine_async_result(
-    basic_stackless_context<Handler, Signature>* c)
+    stackless_context<Handler, Signature>* c)
 {
   return &(*c->impl_)->result_value_;
 }
@@ -430,7 +431,7 @@
 
 template <typename Handler, typename Signature>
 template <typename... T>
-void basic_stackless_context<Handler, Signature>::complete(T&&... args)
+void stackless_context<Handler, Signature>::complete(T&&... args)
 {
   if (!(*impl_)->completed_)
   {
@@ -442,7 +443,7 @@
 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 
 template <typename Handler, typename Signature>
-void basic_stackless_context<Handler, Signature>::complete()
+void stackless_context<Handler, Signature>::complete()
 {
   if (!(*impl_)->completed_)
   {
@@ -454,7 +455,7 @@
 // A macro that should expand to:
 //   template <typename Handler, typename Signature>
 //   template <typename T1, ..., typename Tn>
-//   void basic_stackless_context<Handler, Signature>::complete(
+//   void stackless_context<Handler, Signature>::complete(
 //       const T1& x1, ..., const Tn& xn)
 //   {
 //     if (!(*impl_)->completed_)
@@ -468,7 +469,7 @@
 # define ASIO_PRIVATE_COMPLETE_DEF(n) \
   template <typename Handler, typename Signature> \
   template <ASIO_VARIADIC_TPARAMS(n)> \
-  void basic_stackless_context<Handler, Signature>::complete( \
+  void stackless_context<Handler, Signature>::complete( \
       ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
   { \
     if (!(*impl_)->completed_) \
@@ -485,6 +486,18 @@
 
 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 
+template <typename Function>
+void go(ASIO_MOVE_ARG(Function) function)
+{
+  typedef typename remove_const<
+    typename remove_reference<Function>::type>::type
+      function_type;
+
+  detail::go_helper<void, void(), function_type>(
+      &detail::default_go_handler,
+      ASIO_MOVE_CAST(Function)(function))();
+}
+
 template <typename Handler, typename Function>
 ASIO_INITFN_RESULT_TYPE(Handler, void ())
 go(ASIO_MOVE_ARG(Handler) handler,
@@ -542,7 +555,7 @@
 }
 
 template <typename Handler, typename Function>
-void go(basic_stackless_context<Handler> ctx,
+void go(stackless_context<Handler> ctx,
     ASIO_MOVE_ARG(Function) function)
 {
   Handler handler(ctx.handler_);
@@ -554,16 +567,26 @@
 void go(asio::io_service::strand strand,
     ASIO_MOVE_ARG(Function) function)
 {
-  asio::go(strand.wrap(&detail::default_go_handler),
-      ASIO_MOVE_CAST(Function)(function));
+  typedef typename remove_const<
+    typename remove_reference<Function>::type>::type
+      function_type;
+
+  detail::go_helper<asio::io_service::strand, void(), function_type>(
+      strand.wrap(&detail::default_go_handler),
+      ASIO_MOVE_CAST(Function)(function))();
 }
 
 template <typename Function>
 void go(asio::io_service& io_service,
     ASIO_MOVE_ARG(Function) function)
 {
-  asio::go(asio::io_service::strand(io_service),
-      ASIO_MOVE_CAST(Function)(function));
+  typedef typename remove_const<
+    typename remove_reference<Function>::type>::type
+      function_type;
+
+  detail::go_helper<asio::io_service, void(), function_type>(
+      io_service.wrap(&detail::default_go_handler),
+      ASIO_MOVE_CAST(Function)(function))();
 }
 
 #endif // !defined(GENERATING_DOCUMENTATION)
diff --git a/asio/src/examples/cpp11/go/echo_server.cpp b/asio/src/examples/cpp11/go/echo_server.cpp
index d628aa3..2724683 100644
--- a/asio/src/examples/cpp11/go/echo_server.cpp
+++ b/asio/src/examples/cpp11/go/echo_server.cpp
@@ -26,8 +26,7 @@
 public:
   explicit session(tcp::socket socket)
     : socket_(std::move(socket)),
-      timer_(socket_.get_io_service()),
-      strand_(socket_.get_io_service())
+      timer_(socket_.get_io_service())
   {
   }
 
@@ -38,8 +37,9 @@
     std::size_t n = 0;
     std::array<char, 128> data;
 
-    asio::go(strand_,
-        [this, self, n, data](asio::stackless_context ctx) mutable
+    asio::go(
+        [this, self, n, data]
+        (asio::stackless_context<void> ctx) mutable
         {
           try
           {
@@ -62,8 +62,9 @@
 
     asio::error_code ignored_ec;
 
-    asio::go(strand_,
-        [this, self, ignored_ec](asio::stackless_context ctx) mutable
+    asio::go(
+        [this, self, ignored_ec]
+        (asio::stackless_context<void> ctx) mutable
         {
           reenter (ctx)
           {
@@ -80,7 +81,6 @@
 private:
   tcp::socket socket_;
   asio::steady_timer timer_;
-  asio::io_service::strand strand_;
 };
 
 int main(int argc, char* argv[])
@@ -99,8 +99,8 @@
     tcp::socket socket(io_service);
     asio::error_code ec;
 
-    asio::go(io_service,
-        [&](asio::stackless_context ctx)
+    asio::go(
+        [&](asio::stackless_context<void> ctx)
         {
           reenter (ctx)
           {