Move spawn implementation to separate file.
diff --git a/asio/include/Makefile.am b/asio/include/Makefile.am
index 1c18660..820d1c2 100644
--- a/asio/include/Makefile.am
+++ b/asio/include/Makefile.am
@@ -245,6 +245,7 @@
 	asio/impl/read_until.hpp \
 	asio/impl/serial_port_base.hpp \
 	asio/impl/serial_port_base.ipp \
+	asio/impl/spawn.hpp \
 	asio/impl/src.cpp \
 	asio/impl/src.hpp \
 	asio/impl/write_at.hpp \
diff --git a/asio/include/asio/impl/spawn.hpp b/asio/include/asio/impl/spawn.hpp
new file mode 100644
index 0000000..c6e9b23
--- /dev/null
+++ b/asio/include/asio/impl/spawn.hpp
@@ -0,0 +1,317 @@
+//
+// impl/spawn.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_IMPL_SPAWN_HPP
+#define ASIO_IMPL_SPAWN_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/async_result.hpp"
+#include "asio/detail/handler_alloc_helpers.hpp"
+#include "asio/detail/handler_invoke_helpers.hpp"
+#include "asio/detail/noncopyable.hpp"
+#include "asio/detail/shared_ptr.hpp"
+#include "asio/handler_type.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+  template <typename Handler, typename T>
+  class coro_handler
+  {
+  public:
+    coro_handler(basic_yield_context<Handler> ctx)
+      : coro_(ctx.coro_.lock()),
+        ca_(ctx.ca_),
+        handler_(ctx.handler_),
+        ec_(ctx.ec_),
+        value_(0)
+    {
+    }
+
+    void operator()(T value)
+    {
+      *ec_ = asio::error_code();
+      *value_ = value;
+      (*coro_)();
+    }
+
+    void operator()(asio::error_code ec, T value)
+    {
+      *ec_ = ec;
+      *value_ = value;
+      (*coro_)();
+    }
+
+  //private:
+    detail::shared_ptr<boost::coroutines::coroutine<void()> > coro_;
+    boost::coroutines::coroutine<void()>::caller_type& ca_;
+    Handler& handler_;
+    asio::error_code* ec_;
+    T* value_;
+  };
+
+  template <typename Handler>
+  class coro_handler<Handler, void>
+  {
+  public:
+    coro_handler(basic_yield_context<Handler> ctx)
+      : coro_(ctx.coro_.lock()),
+        ca_(ctx.ca_),
+        handler_(ctx.handler_),
+        ec_(ctx.ec_)
+    {
+    }
+
+    void operator()()
+    {
+      *ec_ = asio::error_code();
+      (*coro_)();
+    }
+
+    void operator()(asio::error_code ec)
+    {
+      *ec_ = ec;
+      (*coro_)();
+    }
+
+  //private:
+    detail::shared_ptr<boost::coroutines::coroutine<void()> > coro_;
+    boost::coroutines::coroutine<void()>::caller_type& ca_;
+    Handler& handler_;
+    asio::error_code* ec_;
+  };
+
+  template <typename Handler, typename T>
+  inline void* asio_handler_allocate(std::size_t size,
+      coro_handler<Handler, T>* this_handler)
+  {
+    return asio_handler_alloc_helpers::allocate(
+        size, this_handler->handler_);
+  }
+
+  template <typename Handler, typename T>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      coro_handler<Handler, T>* this_handler)
+  {
+    asio_handler_alloc_helpers::deallocate(
+        pointer, size, this_handler->handler_);
+  }
+
+  template <typename Function, typename Handler, typename T>
+  inline void asio_handler_invoke(Function& function,
+      coro_handler<Handler, T>* this_handler)
+  {
+    asio_handler_invoke_helpers::invoke(
+        function, this_handler->handler_);
+  }
+
+  template <typename Function, typename Handler, typename T>
+  inline void asio_handler_invoke(const Function& function,
+      coro_handler<Handler, T>* this_handler)
+  {
+    asio_handler_invoke_helpers::invoke(
+        function, this_handler->handler_);
+  }
+
+} // namespace detail
+
+template <typename Handler, typename ReturnType>
+struct handler_type<basic_yield_context<Handler>, ReturnType()>
+{
+  typedef detail::coro_handler<Handler, void> type;
+};
+
+template <typename Handler, typename ReturnType, typename Arg1>
+struct handler_type<basic_yield_context<Handler>, ReturnType(Arg1)>
+{
+  typedef detail::coro_handler<Handler, Arg1> type;
+};
+
+template <typename Handler, typename ReturnType>
+struct handler_type<basic_yield_context<Handler>,
+    ReturnType(asio::error_code)>
+{
+  typedef detail::coro_handler<Handler, void> type;
+};
+
+template <typename Handler, typename ReturnType, typename Arg2>
+struct handler_type<basic_yield_context<Handler>,
+    ReturnType(asio::error_code, Arg2)>
+{
+  typedef detail::coro_handler<Handler, Arg2> type;
+};
+
+template <typename Handler, typename T>
+class async_result<detail::coro_handler<Handler, T> >
+{
+public:
+  typedef T type;
+
+  explicit async_result(detail::coro_handler<Handler, T>& h)
+    : ca_(h.ca_)
+  {
+    out_ec_ = h.ec_;
+    if (!out_ec_) h.ec_ = &ec_;
+    h.value_ = &value_;
+  }
+
+  type get()
+  {
+    ca_();
+    if (!out_ec_ && ec_) throw asio::system_error(ec_);
+    return value_;
+  }
+
+private:
+  boost::coroutines::coroutine<void()>::caller_type& ca_;
+  asio::error_code* out_ec_;
+  asio::error_code ec_;
+  type value_;
+};
+
+template <typename Handler>
+class async_result<detail::coro_handler<Handler, void> >
+{
+public:
+  typedef void type;
+
+  explicit async_result(detail::coro_handler<Handler, void>& h)
+    : ca_(h.ca_)
+  {
+    out_ec_ = h.ec_;
+    if (!out_ec_) h.ec_ = &ec_;
+  }
+
+  void get()
+  {
+    ca_();
+    if (!out_ec_ && ec_) throw asio::system_error(ec_);
+  }
+
+private:
+  boost::coroutines::coroutine<void()>::caller_type& ca_;
+  asio::error_code* out_ec_;
+  asio::error_code ec_;
+};
+
+namespace detail {
+
+  template <typename Handler, typename Function>
+  struct spawn_data : private noncopyable
+  {
+    spawn_data(ASIO_MOVE_ARG(Handler) handler,
+        bool call_handler, ASIO_MOVE_ARG(Function) function)
+      : handler_(ASIO_MOVE_CAST(Handler)(handler)),
+        call_handler_(call_handler),
+        function_(ASIO_MOVE_CAST(Function)(function))
+    {
+    }
+
+    weak_ptr<boost::coroutines::coroutine<void()> > coro_;
+    Handler handler_;
+    bool call_handler_;
+    Function function_;
+  };
+
+  template <typename Handler, typename Function>
+  struct coro_entry_point
+  {
+    void operator()(boost::coroutines::coroutine<void()>::caller_type& ca)
+    {
+      shared_ptr<spawn_data<Handler, Function> > data(data_);
+      ca(); // Yield until coroutine pointer has been initialised.
+      const basic_yield_context<Handler> yield(
+          data->coro_, ca, data->handler_);
+      (data->function_)(yield);
+      if (data->call_handler_)
+        (data->handler_)();
+    }
+
+    shared_ptr<spawn_data<Handler, Function> > data_;
+  };
+
+  template <typename Handler, typename Function>
+  struct spawn_helper
+  {
+    void operator()()
+    {
+      coro_entry_point<Handler, Function> entry_point = { data_ };
+      shared_ptr<boost::coroutines::coroutine<void()> > coro(
+          new boost::coroutines::coroutine<void()>(entry_point, attributes_));
+      data_->coro_ = coro;
+      (*coro)();
+    }
+
+    shared_ptr<spawn_data<Handler, Function> > data_;
+    boost::coroutines::attributes attributes_;
+  };
+
+  inline void default_spawn_handler() {}
+
+} // namespace detail
+
+template <typename Handler, typename Function>
+void spawn(ASIO_MOVE_ARG(Handler) handler,
+    ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  detail::spawn_helper<Handler, Function> helper;
+  helper.data_.reset(
+      new detail::spawn_data<Handler, Function>(
+        ASIO_MOVE_CAST(Handler)(handler), true,
+        ASIO_MOVE_CAST(Function)(function)));
+  helper.attributes_ = attributes;
+  asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
+}
+
+template <typename Handler, typename Function>
+void spawn(basic_yield_context<Handler> ctx,
+    ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  Handler handler(ctx.handler_); // Explicit copy that might be moved from.
+  detail::spawn_helper<Handler, Function> helper;
+  helper.data_.reset(
+      new detail::spawn_data<Handler, Function>(
+        ASIO_MOVE_CAST(Handler)(handler), false,
+        ASIO_MOVE_CAST(Function)(function)));
+  helper.attributes_ = attributes;
+  asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
+}
+
+template <typename Function>
+void spawn(asio::io_service::strand strand,
+    ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  asio::spawn(strand.wrap(&detail::default_spawn_handler),
+      ASIO_MOVE_CAST(Function)(function), attributes);
+}
+
+template <typename Function>
+void spawn(asio::io_service& io_service,
+    ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  asio::spawn(asio::io_service::strand(io_service),
+      ASIO_MOVE_CAST(Function)(function), attributes);
+}
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_IMPL_SPAWN_HPP
diff --git a/asio/include/asio/spawn.hpp b/asio/include/asio/spawn.hpp
index 7a06c1c..d05ab42 100644
--- a/asio/include/asio/spawn.hpp
+++ b/asio/include/asio/spawn.hpp
@@ -17,14 +17,8 @@
 
 #include "asio/detail/config.hpp"
 #include <boost/coroutine/coroutine.hpp>
-#include "asio/async_result.hpp"
-#include "asio/detail/bind_handler.hpp"
-#include "asio/detail/handler_invoke_helpers.hpp"
-#include "asio/detail/noncopyable.hpp"
-#include "asio/detail/shared_ptr.hpp"
 #include "asio/detail/weak_ptr.hpp"
 #include "asio/detail/wrapped_handler.hpp"
-#include "asio/handler_type.hpp"
 #include "asio/io_service.hpp"
 #include "asio/strand.hpp"
 
@@ -64,276 +58,34 @@
   detail::wrapped_handler<
     io_service::strand, void(*)()> > yield_context;
 
-template <typename Handler, typename T>
-class coro_handler
-{
-public:
-  coro_handler(basic_yield_context<Handler> ctx)
-    : coro_(ctx.coro_.lock()),
-      ca_(ctx.ca_),
-      handler_(ctx.handler_),
-      ec_(ctx.ec_),
-      value_(0)
-  {
-  }
-
-  void operator()(T value)
-  {
-    *ec_ = asio::error_code();
-    *value_ = value;
-    (*coro_)();
-  }
-
-  void operator()(asio::error_code ec, T value)
-  {
-    *ec_ = ec;
-    *value_ = value;
-    (*coro_)();
-  }
-
-//private:
-  detail::shared_ptr<boost::coroutines::coroutine<void()> > coro_;
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
-  Handler& handler_;
-  asio::error_code* ec_;
-  T* value_;
-};
-
-template <typename Handler>
-class coro_handler<Handler, void>
-{
-public:
-  coro_handler(basic_yield_context<Handler> ctx)
-    : coro_(ctx.coro_.lock()),
-      ca_(ctx.ca_),
-      handler_(ctx.handler_),
-      ec_(ctx.ec_)
-  {
-  }
-
-  void operator()()
-  {
-    *ec_ = asio::error_code();
-    (*coro_)();
-  }
-
-  void operator()(asio::error_code ec)
-  {
-    *ec_ = ec;
-    (*coro_)();
-  }
-
-//private:
-  detail::shared_ptr<boost::coroutines::coroutine<void()> > coro_;
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
-  Handler& handler_;
-  asio::error_code* ec_;
-};
-
-template <typename Function, typename Handler, typename T>
-inline void asio_handler_invoke(Function& function,
-    coro_handler<Handler, T>* this_handler)
-{
-  asio_handler_invoke_helpers::invoke(
-      function, this_handler->handler_);
-}
-
-template <typename Function, typename Handler, typename T>
-inline void asio_handler_invoke(const Function& function,
-    coro_handler<Handler, T>* this_handler)
-{
-  asio_handler_invoke_helpers::invoke(
-      function, this_handler->handler_);
-}
-
-template <typename Handler, typename ReturnType>
-struct handler_type<basic_yield_context<Handler>, ReturnType()>
-{
-  typedef coro_handler<Handler, void> type;
-};
-
-template <typename Handler, typename ReturnType, typename Arg1>
-struct handler_type<basic_yield_context<Handler>, ReturnType(Arg1)>
-{
-  typedef coro_handler<Handler, Arg1> type;
-};
-
-template <typename Handler, typename ReturnType>
-struct handler_type<basic_yield_context<Handler>,
-    ReturnType(asio::error_code)>
-{
-  typedef coro_handler<Handler, void> type;
-};
-
-template <typename Handler, typename ReturnType, typename Arg2>
-struct handler_type<basic_yield_context<Handler>,
-    ReturnType(asio::error_code, Arg2)>
-{
-  typedef coro_handler<Handler, Arg2> type;
-};
-
-template <typename Handler, typename T>
-class async_result<coro_handler<Handler, T> >
-{
-public:
-  typedef T type;
-
-  explicit async_result(coro_handler<Handler, T>& h)
-    : ca_(h.ca_)
-  {
-    out_ec_ = h.ec_;
-    if (!out_ec_) h.ec_ = &ec_;
-    h.value_ = &value_;
-  }
-
-  type get()
-  {
-    ca_();
-    if (!out_ec_ && ec_) throw asio::system_error(ec_);
-    return value_;
-  }
-
-private:
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
-  asio::error_code* out_ec_;
-  asio::error_code ec_;
-  type value_;
-};
-
-template <typename Handler>
-class async_result<coro_handler<Handler, void> >
-{
-public:
-  typedef void type;
-
-  explicit async_result(coro_handler<Handler, void>& h)
-    : ca_(h.ca_)
-  {
-    out_ec_ = h.ec_;
-    if (!out_ec_) h.ec_ = &ec_;
-  }
-
-  void get()
-  {
-    ca_();
-    if (!out_ec_ && ec_) throw asio::system_error(ec_);
-  }
-
-private:
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
-  asio::error_code* out_ec_;
-  asio::error_code ec_;
-};
-
-namespace detail {
-
-  template <typename Handler, typename Function>
-  struct spawn_data : private noncopyable
-  {
-    spawn_data(ASIO_MOVE_ARG(Handler) handler,
-        bool call_handler, ASIO_MOVE_ARG(Function) function)
-      : handler_(ASIO_MOVE_CAST(Handler)(handler)),
-        call_handler_(call_handler),
-        function_(ASIO_MOVE_CAST(Function)(function))
-    {
-    }
-
-    weak_ptr<boost::coroutines::coroutine<void()> > coro_;
-    Handler handler_;
-    bool call_handler_;
-    Function function_;
-  };
-
-  template <typename Handler, typename Function>
-  struct coro_entry_point
-  {
-    void operator()(boost::coroutines::coroutine<void()>::caller_type& ca)
-    {
-      shared_ptr<spawn_data<Handler, Function> > data(data_);
-      ca(); // Yield until coroutine pointer has been initialised.
-      const basic_yield_context<Handler> yield(
-          data->coro_, ca, data->handler_);
-      (data->function_)(yield);
-      if (data->call_handler_)
-        (data->handler_)();
-    }
-
-    shared_ptr<spawn_data<Handler, Function> > data_;
-  };
-
-  template <typename Handler, typename Function>
-  struct spawn_helper
-  {
-    void operator()()
-    {
-      coro_entry_point<Handler, Function> entry_point = { data_ };
-      shared_ptr<boost::coroutines::coroutine<void()> > coro(
-          new boost::coroutines::coroutine<void()>(entry_point, attributes_));
-      data_->coro_ = coro;
-      (*coro)();
-    }
-
-    shared_ptr<spawn_data<Handler, Function> > data_;
-    boost::coroutines::attributes attributes_;
-  };
-
-  inline void default_spawn_handler() {}
-
-} // namespace detail
-
 template <typename Handler, typename Function>
 void spawn(ASIO_MOVE_ARG(Handler) handler,
     ASIO_MOVE_ARG(Function) function,
     const boost::coroutines::attributes& attributes
-      = boost::coroutines::attributes())
-{
-  detail::spawn_helper<Handler, Function> helper;
-  helper.data_.reset(
-      new detail::spawn_data<Handler, Function>(
-        ASIO_MOVE_CAST(Handler)(handler), true,
-        ASIO_MOVE_CAST(Function)(function)));
-  helper.attributes_ = attributes;
-  asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
-}
+      = boost::coroutines::attributes());
 
 template <typename Handler, typename Function>
 void spawn(basic_yield_context<Handler> ctx,
     ASIO_MOVE_ARG(Function) function,
     const boost::coroutines::attributes& attributes
-      = boost::coroutines::attributes())
-{
-  Handler handler(ctx.handler_); // Explicit copy that might be moved from.
-  detail::spawn_helper<Handler, Function> helper;
-  helper.data_.reset(
-      new detail::spawn_data<Handler, Function>(
-        ASIO_MOVE_CAST(Handler)(handler), false,
-        ASIO_MOVE_CAST(Function)(function)));
-  helper.attributes_ = attributes;
-  asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
-}
+      = boost::coroutines::attributes());
 
 template <typename Function>
 void spawn(asio::io_service::strand strand,
     ASIO_MOVE_ARG(Function) function,
     const boost::coroutines::attributes& attributes
-      = boost::coroutines::attributes())
-{
-  asio::spawn(strand.wrap(&detail::default_spawn_handler),
-      ASIO_MOVE_CAST(Function)(function), attributes);
-}
+      = boost::coroutines::attributes());
 
 template <typename Function>
 void spawn(asio::io_service& io_service,
     ASIO_MOVE_ARG(Function) function,
     const boost::coroutines::attributes& attributes
-      = boost::coroutines::attributes())
-{
-  asio::spawn(asio::io_service::strand(io_service),
-      ASIO_MOVE_CAST(Function)(function), attributes);
-}
+      = boost::coroutines::attributes());
 
 } // namespace asio
 
 #include "asio/detail/pop_options.hpp"
 
+#include "asio/impl/spawn.hpp"
+
 #endif // ASIO_SPAWN_HPP