Deprecate resolver::query. Use overloads of resolve and async_resolve.
diff --git a/asio/include/Makefile.am b/asio/include/Makefile.am
index e56250d..9ea794a 100644
--- a/asio/include/Makefile.am
+++ b/asio/include/Makefile.am
@@ -353,6 +353,7 @@
 	asio/ip/multicast.hpp \
 	asio/ip/network_v4.hpp \
 	asio/ip/network_v6.hpp \
+	asio/ip/resolver_base.hpp \
 	asio/ip/resolver_query_base.hpp \
 	asio/ip/resolver_service.hpp \
 	asio/ip/tcp.hpp \
diff --git a/asio/include/asio.hpp b/asio/include/asio.hpp
index 4b9e94c..6224787 100644
--- a/asio/include/asio.hpp
+++ b/asio/include/asio.hpp
@@ -79,6 +79,7 @@
 #include "asio/ip/host_name.hpp"
 #include "asio/ip/icmp.hpp"
 #include "asio/ip/multicast.hpp"
+#include "asio/ip/resolver_base.hpp"
 #include "asio/ip/resolver_query_base.hpp"
 #include "asio/ip/resolver_service.hpp"
 #include "asio/ip/tcp.hpp"
diff --git a/asio/include/asio/ip/basic_resolver.hpp b/asio/include/asio/ip/basic_resolver.hpp
index 66016c1..7b9f291 100644
--- a/asio/include/asio/ip/basic_resolver.hpp
+++ b/asio/include/asio/ip/basic_resolver.hpp
@@ -16,6 +16,7 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include "asio/detail/config.hpp"
+#include <string>
 #include "asio/basic_io_object.hpp"
 #include "asio/detail/handler_type_requirements.hpp"
 #include "asio/detail/throw_error.hpp"
@@ -23,6 +24,7 @@
 #include "asio/ip/basic_resolver_iterator.hpp"
 #include "asio/ip/basic_resolver_query.hpp"
 #include "asio/ip/basic_resolver_results.hpp"
+#include "asio/ip/resolver_base.hpp"
 #include "asio/ip/resolver_service.hpp"
 
 #include "asio/detail/push_options.hpp"
@@ -42,7 +44,8 @@
 template <typename InternetProtocol,
     typename ResolverService = resolver_service<InternetProtocol> >
 class basic_resolver
-  : public basic_io_object<ResolverService>
+  : public basic_io_object<ResolverService>,
+    public resolver_base
 {
 public:
   /// The protocol type.
@@ -51,7 +54,7 @@
   /// The endpoint type.
   typedef typename InternetProtocol::endpoint endpoint_type;
 
-  /// The query type.
+  /// (Deprecated.) The query type.
   typedef basic_resolver_query<InternetProtocol> query;
 
   /// (Deprecated.) The iterator type.
@@ -83,7 +86,7 @@
     return this->get_service().cancel(this->get_implementation());
   }
 
-  /// Perform forward resolution of a query to a list of entries.
+  /// (Deprecated.) Perform forward resolution of a query to a list of entries.
   /**
    * This function is used to resolve a query into a list of endpoint entries.
    *
@@ -104,7 +107,7 @@
     return r;
   }
 
-  /// Perform forward resolution of a query to a list of entries.
+  /// (Deprecated.) Perform forward resolution of a query to a list of entries.
   /**
    * This function is used to resolve a query into a list of endpoint entries.
    *
@@ -121,7 +124,360 @@
     return this->get_service().resolve(this->get_implementation(), q, ec);
   }
 
-  /// Asynchronously perform forward resolution of a query to a list of entries.
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @returns A range object representing the list of endpoint entries. A
+   * successful call to this function is guaranteed to return a non-empty
+   * range.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const std::string& host, const std::string& service)
+  {
+    return resolve(host, service, resolver_base::flags());
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns A range object representing the list of endpoint entries. An
+   * empty range is returned if an error occurs. A successful call to this
+   * function is guaranteed to return a non-empty range.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const std::string& host, const std::string& service,
+      asio::error_code& ec)
+  {
+    return resolve(host, service, resolver_base::flags(), ec);
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param resolve_flags A set of flags that determine how name resolution
+   * should be performed. The default flags are suitable for communication with
+   * remote hosts.
+   *
+   * @returns A range object representing the list of endpoint entries. A
+   * successful call to this function is guaranteed to return a non-empty
+   * range.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const std::string& host, const std::string& service,
+      resolver_base::flags resolve_flags)
+  {
+    asio::error_code ec;
+    query q(host, service, resolve_flags);
+    results_type r = this->get_service().resolve(
+        this->get_implementation(), q, ec);
+    asio::detail::throw_error(ec, "resolve");
+    return r;
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param resolve_flags A set of flags that determine how name resolution
+   * should be performed. The default flags are suitable for communication with
+   * remote hosts.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns A range object representing the list of endpoint entries. An
+   * empty range is returned if an error occurs. A successful call to this
+   * function is guaranteed to return a non-empty range.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const std::string& host, const std::string& service,
+      resolver_base::flags resolve_flags, asio::error_code& ec)
+  {
+    query q(host, service, resolve_flags);
+    return this->get_service().resolve(this->get_implementation(), q, ec);
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param protocol A protocol object, normally representing either the IPv4 or
+   * IPv6 version of an internet protocol.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @returns A range object representing the list of endpoint entries. A
+   * successful call to this function is guaranteed to return a non-empty
+   * range.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const protocol_type& protocol, const std::string& host,
+      const std::string& service)
+  {
+    return resolve(protocol, host, service, resolver_base::flags());
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param protocol A protocol object, normally representing either the IPv4 or
+   * IPv6 version of an internet protocol.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns A range object representing the list of endpoint entries. An
+   * empty range is returned if an error occurs. A successful call to this
+   * function is guaranteed to return a non-empty range.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const protocol_type& protocol, const std::string& host,
+      const std::string& service, asio::error_code& ec)
+  {
+    return resolve(protocol, host, service, resolver_base::flags(), ec);
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param protocol A protocol object, normally representing either the IPv4 or
+   * IPv6 version of an internet protocol.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param resolve_flags A set of flags that determine how name resolution
+   * should be performed. The default flags are suitable for communication with
+   * remote hosts.
+   *
+   * @returns A range object representing the list of endpoint entries. A
+   * successful call to this function is guaranteed to return a non-empty
+   * range.
+   *
+   * @throws asio::system_error Thrown on failure.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const protocol_type& protocol, const std::string& host,
+      const std::string& service, resolver_base::flags resolve_flags)
+  {
+    asio::error_code ec;
+    query q(protocol, host, service, resolve_flags);
+    results_type r = this->get_service().resolve(
+        this->get_implementation(), q, ec);
+    asio::detail::throw_error(ec, "resolve");
+    return r;
+  }
+
+  /// Perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param protocol A protocol object, normally representing either the IPv4 or
+   * IPv6 version of an internet protocol.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param resolve_flags A set of flags that determine how name resolution
+   * should be performed. The default flags are suitable for communication with
+   * remote hosts.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns A range object representing the list of endpoint entries. An
+   * empty range is returned if an error occurs. A successful call to this
+   * function is guaranteed to return a non-empty range.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  results_type resolve(const protocol_type& protocol, const std::string& host,
+      const std::string& service, resolver_base::flags resolve_flags,
+      asio::error_code& ec)
+  {
+    query q(protocol, host, service, resolve_flags);
+    return this->get_service().resolve(this->get_implementation(), q, ec);
+  }
+
+  /// (Deprecated.) Asynchronously perform forward resolution of a query to a
+  /// list of entries.
   /**
    * This function is used to asynchronously resolve a query into a list of
    * endpoint entries.
@@ -158,6 +514,242 @@
         ASIO_MOVE_CAST(ResolveHandler)(handler));
   }
 
+  /// Asynchronously perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param handler The handler to be called when the resolve 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.
+   *   resolver::results_type results // Resolved endpoints as a range.
+   * ); @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().
+   *
+   * A successful resolve operation is guaranteed to pass a non-empty range to
+   * the handler.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  template <typename ResolveHandler>
+  ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+      void (asio::error_code, results_type))
+  async_resolve(const std::string& host, const std::string& service,
+      ASIO_MOVE_ARG(ResolveHandler) handler)
+  {
+    return async_resolve(host, service, resolver_base::flags(),
+        ASIO_MOVE_CAST(ResolveHandler)(handler));
+  }
+
+  /// Asynchronously perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param resolve_flags A set of flags that determine how name resolution
+   * should be performed. The default flags are suitable for communication with
+   * remote hosts.
+   *
+   * @param handler The handler to be called when the resolve 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.
+   *   resolver::results_type results // Resolved endpoints as a range.
+   * ); @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().
+   *
+   * A successful resolve operation is guaranteed to pass a non-empty range to
+   * the handler.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  template <typename ResolveHandler>
+  ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+      void (asio::error_code, results_type))
+  async_resolve(const std::string& host, const std::string& service,
+      resolver_base::flags resolve_flags,
+      ASIO_MOVE_ARG(ResolveHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ResolveHandler.
+    ASIO_RESOLVE_HANDLER_CHECK(
+        ResolveHandler, handler, results_type) type_check;
+
+    query q(host, service, resolve_flags);
+    return this->get_service().async_resolve(this->get_implementation(), q,
+        ASIO_MOVE_CAST(ResolveHandler)(handler));
+  }
+
+  /// Asynchronously perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param protocol A protocol object, normally representing either the IPv4 or
+   * IPv6 version of an internet protocol.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param handler The handler to be called when the resolve 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.
+   *   resolver::results_type results // Resolved endpoints as a range.
+   * ); @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().
+   *
+   * A successful resolve operation is guaranteed to pass a non-empty range to
+   * the handler.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  template <typename ResolveHandler>
+  ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+      void (asio::error_code, results_type))
+  async_resolve(const protocol_type& protocol, const std::string& host,
+      const std::string& service, ASIO_MOVE_ARG(ResolveHandler) handler)
+  {
+    return async_resolve(protocol, host, service, resolver_base::flags(),
+        ASIO_MOVE_CAST(ResolveHandler)(handler));
+  }
+
+  /// Asynchronously perform forward resolution of a query to a list of entries.
+  /**
+   * This function is used to resolve host and service names into a list of
+   * endpoint entries.
+   *
+   * @param protocol A protocol object, normally representing either the IPv4 or
+   * IPv6 version of an internet protocol.
+   *
+   * @param host A string identifying a location. May be a descriptive name or
+   * a numeric address string. If an empty string and the passive flag has been
+   * specified, the resolved endpoints are suitable for local service binding.
+   * If an empty string and passive is not specified, the resolved endpoints
+   * will use the loopback address.
+   *
+   * @param service A string identifying the requested service. This may be a
+   * descriptive name or a numeric string corresponding to a port number. May
+   * be an empty string, in which case all resolved endpoints will have a port
+   * number of 0.
+   *
+   * @param resolve_flags A set of flags that determine how name resolution
+   * should be performed. The default flags are suitable for communication with
+   * remote hosts.
+   *
+   * @param handler The handler to be called when the resolve 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.
+   *   resolver::results_type results // Resolved endpoints as a range.
+   * ); @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().
+   *
+   * A successful resolve operation is guaranteed to pass a non-empty range to
+   * the handler.
+   *
+   * @note On POSIX systems, host names may be locally defined in the file
+   * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
+   * resolution is performed using DNS. Operating systems may use additional
+   * locations when resolving host names (such as NETBIOS names on Windows).
+   *
+   * On POSIX systems, service names are typically defined in the file
+   * <tt>/etc/services</tt>. On Windows, service names may be found in the file
+   * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
+   * may use additional locations when resolving service names.
+   */
+  template <typename ResolveHandler>
+  ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+      void (asio::error_code, results_type))
+  async_resolve(const protocol_type& protocol, const std::string& host,
+      const std::string& service, resolver_base::flags resolve_flags,
+      ASIO_MOVE_ARG(ResolveHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ResolveHandler.
+    ASIO_RESOLVE_HANDLER_CHECK(
+        ResolveHandler, handler, results_type) type_check;
+
+    query q(protocol, host, service, resolve_flags);
+    return this->get_service().async_resolve(this->get_implementation(), q,
+        ASIO_MOVE_CAST(ResolveHandler)(handler));
+  }
+
   /// Perform reverse resolution of an endpoint to a list of entries.
   /**
    * This function is used to resolve an endpoint into a list of endpoint
diff --git a/asio/include/asio/ip/resolver_base.hpp b/asio/include/asio/ip/resolver_base.hpp
new file mode 100644
index 0000000..f7e0a85
--- /dev/null
+++ b/asio/include/asio/ip/resolver_base.hpp
@@ -0,0 +1,129 @@
+//
+// ip/resolver_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2015 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_IP_RESOLVER_BASE_HPP
+#define ASIO_IP_RESOLVER_BASE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/detail/socket_types.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace ip {
+
+/// The resolver_base class is used as a base for the basic_resolver class
+/// templates to provide a common place to define the flag constants.
+class resolver_base
+{
+public:
+#if defined(GENERATING_DOCUMENTATION)
+  /// A bitmask type (C++ Std [lib.bitmask.types]).
+  typedef unspecified flags;
+
+  /// Determine the canonical name of the host specified in the query.
+  static const flags canonical_name = implementation_defined;
+
+  /// Indicate that returned endpoint is intended for use as a locally bound
+  /// socket endpoint.
+  static const flags passive = implementation_defined;
+
+  /// Host name should be treated as a numeric string defining an IPv4 or IPv6
+  /// address and no name resolution should be attempted.
+  static const flags numeric_host = implementation_defined;
+
+  /// Service name should be treated as a numeric string defining a port number
+  /// and no name resolution should be attempted.
+  static const flags numeric_service = implementation_defined;
+
+  /// If the query protocol family is specified as IPv6, return IPv4-mapped
+  /// IPv6 addresses on finding no IPv6 addresses.
+  static const flags v4_mapped = implementation_defined;
+
+  /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses.
+  static const flags all_matching = implementation_defined;
+
+  /// Only return IPv4 addresses if a non-loopback IPv4 address is configured
+  /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address
+  /// is configured for the system.
+  static const flags address_configured = implementation_defined;
+#else
+  enum flags
+  {
+    canonical_name = ASIO_OS_DEF(AI_CANONNAME),
+    passive = ASIO_OS_DEF(AI_PASSIVE),
+    numeric_host = ASIO_OS_DEF(AI_NUMERICHOST),
+    numeric_service = ASIO_OS_DEF(AI_NUMERICSERV),
+    v4_mapped = ASIO_OS_DEF(AI_V4MAPPED),
+    all_matching = ASIO_OS_DEF(AI_ALL),
+    address_configured = ASIO_OS_DEF(AI_ADDRCONFIG)
+  };
+
+  // Implement bitmask operations as shown in C++ Std [lib.bitmask.types].
+
+  friend flags operator&(flags x, flags y)
+  {
+    return static_cast<flags>(
+        static_cast<unsigned int>(x) & static_cast<unsigned int>(y));
+  }
+
+  friend flags operator|(flags x, flags y)
+  {
+    return static_cast<flags>(
+        static_cast<unsigned int>(x) | static_cast<unsigned int>(y));
+  }
+
+  friend flags operator^(flags x, flags y)
+  {
+    return static_cast<flags>(
+        static_cast<unsigned int>(x) ^ static_cast<unsigned int>(y));
+  }
+
+  friend flags operator~(flags x)
+  {
+    return static_cast<flags>(~static_cast<unsigned int>(x));
+  }
+
+  friend flags& operator&=(flags& x, flags y)
+  {
+    x = x & y;
+    return x;
+  }
+
+  friend flags& operator|=(flags& x, flags y)
+  {
+    x = x | y;
+    return x;
+  }
+
+  friend flags& operator^=(flags& x, flags y)
+  {
+    x = x ^ y;
+    return x;
+  }
+#endif
+
+protected:
+  /// Protected destructor to prevent deletion through this type.
+  ~resolver_base()
+  {
+  }
+};
+
+} // namespace ip
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_IP_RESOLVER_BASE_HPP
diff --git a/asio/include/asio/ip/resolver_query_base.hpp b/asio/include/asio/ip/resolver_query_base.hpp
index bd1bde5..60bc005 100644
--- a/asio/include/asio/ip/resolver_query_base.hpp
+++ b/asio/include/asio/ip/resolver_query_base.hpp
@@ -16,7 +16,7 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include "asio/detail/config.hpp"
-#include "asio/detail/socket_types.hpp"
+#include "asio/ip/resolver_base.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -26,95 +26,8 @@
 /// The resolver_query_base class is used as a base for the
 /// basic_resolver_query class templates to provide a common place to define
 /// the flag constants.
-class resolver_query_base
+class resolver_query_base : public resolver_base
 {
-public:
-#if defined(GENERATING_DOCUMENTATION)
-  /// A bitmask type (C++ Std [lib.bitmask.types]).
-  typedef unspecified flags;
-
-  /// Determine the canonical name of the host specified in the query.
-  static const flags canonical_name = implementation_defined;
-
-  /// Indicate that returned endpoint is intended for use as a locally bound
-  /// socket endpoint.
-  static const flags passive = implementation_defined;
-
-  /// Host name should be treated as a numeric string defining an IPv4 or IPv6
-  /// address and no name resolution should be attempted.
-  static const flags numeric_host = implementation_defined;
-
-  /// Service name should be treated as a numeric string defining a port number
-  /// and no name resolution should be attempted.
-  static const flags numeric_service = implementation_defined;
-
-  /// If the query protocol family is specified as IPv6, return IPv4-mapped
-  /// IPv6 addresses on finding no IPv6 addresses.
-  static const flags v4_mapped = implementation_defined;
-
-  /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses.
-  static const flags all_matching = implementation_defined;
-
-  /// Only return IPv4 addresses if a non-loopback IPv4 address is configured
-  /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address
-  /// is configured for the system.
-  static const flags address_configured = implementation_defined;
-#else
-  enum flags
-  {
-    canonical_name = ASIO_OS_DEF(AI_CANONNAME),
-    passive = ASIO_OS_DEF(AI_PASSIVE),
-    numeric_host = ASIO_OS_DEF(AI_NUMERICHOST),
-    numeric_service = ASIO_OS_DEF(AI_NUMERICSERV),
-    v4_mapped = ASIO_OS_DEF(AI_V4MAPPED),
-    all_matching = ASIO_OS_DEF(AI_ALL),
-    address_configured = ASIO_OS_DEF(AI_ADDRCONFIG)
-  };
-
-  // Implement bitmask operations as shown in C++ Std [lib.bitmask.types].
-
-  friend flags operator&(flags x, flags y)
-  {
-    return static_cast<flags>(
-        static_cast<unsigned int>(x) & static_cast<unsigned int>(y));
-  }
-
-  friend flags operator|(flags x, flags y)
-  {
-    return static_cast<flags>(
-        static_cast<unsigned int>(x) | static_cast<unsigned int>(y));
-  }
-
-  friend flags operator^(flags x, flags y)
-  {
-    return static_cast<flags>(
-        static_cast<unsigned int>(x) ^ static_cast<unsigned int>(y));
-  }
-
-  friend flags operator~(flags x)
-  {
-    return static_cast<flags>(~static_cast<unsigned int>(x));
-  }
-
-  friend flags& operator&=(flags& x, flags y)
-  {
-    x = x & y;
-    return x;
-  }
-
-  friend flags& operator|=(flags& x, flags y)
-  {
-    x = x | y;
-    return x;
-  }
-
-  friend flags& operator^=(flags& x, flags y)
-  {
-    x = x ^ y;
-    return x;
-  }
-#endif
-
 protected:
   /// Protected destructor to prevent deletion through this type.
   ~resolver_query_base()
diff --git a/asio/src/examples/cpp03/chat/chat_client.cpp b/asio/src/examples/cpp03/chat/chat_client.cpp
index 206dea2..ca66747 100644
--- a/asio/src/examples/cpp03/chat/chat_client.cpp
+++ b/asio/src/examples/cpp03/chat/chat_client.cpp
@@ -148,8 +148,7 @@
     asio::io_service io_service;
 
     tcp::resolver resolver(io_service);
-    tcp::resolver::query query(argv[1], argv[2]);
-    tcp::resolver::results_type endpoints = resolver.resolve(query);
+    tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
 
     chat_client c(io_service, endpoints);
 
diff --git a/asio/src/examples/cpp03/chat/posix_chat_client.cpp b/asio/src/examples/cpp03/chat/posix_chat_client.cpp
index 3185d5d..f25872c 100644
--- a/asio/src/examples/cpp03/chat/posix_chat_client.cpp
+++ b/asio/src/examples/cpp03/chat/posix_chat_client.cpp
@@ -185,8 +185,7 @@
     asio::io_service io_service;
 
     tcp::resolver resolver(io_service);
-    tcp::resolver::query query(argv[1], argv[2]);
-    tcp::resolver::results_type endpoints = resolver.resolve(query);
+    tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
 
     posix_chat_client c(io_service, endpoints);
 
diff --git a/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp b/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp
index fda4baa..202e5d9 100644
--- a/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp
+++ b/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp
@@ -30,8 +30,8 @@
     asio::io_service io_service;
 
     tcp::resolver resolver(io_service);
-    tcp::resolver::query query(tcp::v4(), argv[1], argv[2]);
-    tcp::resolver::results_type endpoints = resolver.resolve(query);
+    tcp::resolver::results_type endpoints =
+      resolver.resolve(tcp::v4(), argv[1], argv[2]);
 
     tcp::socket s(io_service);
     asio::connect(s, endpoints);
diff --git a/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp b/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp
index ec08895..5c0c88c 100644
--- a/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp
+++ b/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp
@@ -32,8 +32,8 @@
     udp::socket s(io_service, udp::endpoint(udp::v4(), 0));
 
     udp::resolver resolver(io_service);
-    udp::resolver::query query(udp::v4(), argv[1], argv[2]);
-    udp::resolver::iterator iterator = resolver.resolve(query);
+    udp::resolver::iterator iterator =
+      resolver.resolve(udp::v4(), argv[1], argv[2]);
 
     using namespace std; // For strlen.
     std::cout << "Enter message: ";
diff --git a/asio/src/examples/cpp03/http/client/async_client.cpp b/asio/src/examples/cpp03/http/client/async_client.cpp
index a1c6009..fa9b625 100644
--- a/asio/src/examples/cpp03/http/client/async_client.cpp
+++ b/asio/src/examples/cpp03/http/client/async_client.cpp
@@ -36,8 +36,7 @@
 
     // Start an asynchronous resolve to translate the server and service names
     // into a list of endpoints.
-    tcp::resolver::query query(server, "http");
-    resolver_.async_resolve(query,
+    resolver_.async_resolve(server, "http",
         boost::bind(&client::handle_resolve, this,
           asio::placeholders::error,
           asio::placeholders::results));
diff --git a/asio/src/examples/cpp03/http/client/sync_client.cpp b/asio/src/examples/cpp03/http/client/sync_client.cpp
index 37d7300..d90f1f2 100644
--- a/asio/src/examples/cpp03/http/client/sync_client.cpp
+++ b/asio/src/examples/cpp03/http/client/sync_client.cpp
@@ -32,8 +32,7 @@
 
     // Get a list of endpoints corresponding to the server name.
     tcp::resolver resolver(io_service);
-    tcp::resolver::query query(argv[1], "http");
-    tcp::resolver::results_type endpoints = resolver.resolve(query);
+    tcp::resolver::results_type endpoints = resolver.resolve(argv[1], "http");
 
     // Try each endpoint until we successfully establish a connection.
     tcp::socket socket(io_service);
diff --git a/asio/src/examples/cpp03/http/server/server.cpp b/asio/src/examples/cpp03/http/server/server.cpp
index e72ebcd..b534ea8 100644
--- a/asio/src/examples/cpp03/http/server/server.cpp
+++ b/asio/src/examples/cpp03/http/server/server.cpp
@@ -36,8 +36,8 @@
 
   // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
   asio::ip::tcp::resolver resolver(io_service_);
-  asio::ip::tcp::resolver::query query(address, port);
-  asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
+  asio::ip::tcp::endpoint endpoint =
+    *resolver.resolve(address, port).begin();
   acceptor_.open(endpoint.protocol());
   acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
   acceptor_.bind(endpoint);
diff --git a/asio/src/examples/cpp03/http/server2/server.cpp b/asio/src/examples/cpp03/http/server2/server.cpp
index 688be2c..4ba84de 100644
--- a/asio/src/examples/cpp03/http/server2/server.cpp
+++ b/asio/src/examples/cpp03/http/server2/server.cpp
@@ -34,8 +34,8 @@
 
   // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
   asio::ip::tcp::resolver resolver(acceptor_.get_executor().context());
-  asio::ip::tcp::resolver::query query(address, port);
-  asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
+  asio::ip::tcp::endpoint endpoint =
+    *resolver.resolve(address, port).begin();
   acceptor_.open(endpoint.protocol());
   acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
   acceptor_.bind(endpoint);
diff --git a/asio/src/examples/cpp03/http/server3/server.cpp b/asio/src/examples/cpp03/http/server3/server.cpp
index d2832fe..e26711b 100644
--- a/asio/src/examples/cpp03/http/server3/server.cpp
+++ b/asio/src/examples/cpp03/http/server3/server.cpp
@@ -36,8 +36,8 @@
 
   // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
   asio::ip::tcp::resolver resolver(io_service_);
-  asio::ip::tcp::resolver::query query(address, port);
-  asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
+  asio::ip::tcp::endpoint endpoint =
+    *resolver.resolve(address, port).begin();
   acceptor_.open(endpoint.protocol());
   acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
   acceptor_.bind(endpoint);
diff --git a/asio/src/examples/cpp03/http/server4/server.cpp b/asio/src/examples/cpp03/http/server4/server.cpp
index dd6bfc6..ebb9345 100644
--- a/asio/src/examples/cpp03/http/server4/server.cpp
+++ b/asio/src/examples/cpp03/http/server4/server.cpp
@@ -21,8 +21,9 @@
   : request_handler_(request_handler)
 {
   tcp::resolver resolver(io_service);
-  tcp::resolver::query query(address, port);
-  acceptor_.reset(new tcp::acceptor(io_service, *resolver.resolve(query)));
+  asio::ip::tcp::endpoint endpoint =
+    *resolver.resolve(address, port).begin();
+  acceptor_.reset(new tcp::acceptor(io_service, endpoint));
 }
 
 // Enable the pseudo-keywords reenter, yield and fork.
diff --git a/asio/src/examples/cpp03/icmp/ping.cpp b/asio/src/examples/cpp03/icmp/ping.cpp
index 2d897b0..257fc94 100644
--- a/asio/src/examples/cpp03/icmp/ping.cpp
+++ b/asio/src/examples/cpp03/icmp/ping.cpp
@@ -28,8 +28,7 @@
     : resolver_(io_service), socket_(io_service, icmp::v4()),
       timer_(io_service), sequence_number_(0), num_replies_(0)
   {
-    icmp::resolver::query query(icmp::v4(), destination, "");
-    destination_ = *resolver_.resolve(query);
+    destination_ = *resolver_.resolve(icmp::v4(), destination, "");
 
     start_send();
     start_receive();
diff --git a/asio/src/examples/cpp03/porthopper/client.cpp b/asio/src/examples/cpp03/porthopper/client.cpp
index 9aa2486..832183f 100644
--- a/asio/src/examples/cpp03/porthopper/client.cpp
+++ b/asio/src/examples/cpp03/porthopper/client.cpp
@@ -41,8 +41,7 @@
 
     // Determine the location of the server.
     tcp::resolver resolver(io_service);
-    tcp::resolver::query query(host_name, port);
-    tcp::endpoint remote_endpoint = *resolver.resolve(query);
+    tcp::endpoint remote_endpoint = *resolver.resolve(host_name, port);
 
     // Establish the control connection to the server.
     tcp::socket control_socket(io_service);
diff --git a/asio/src/examples/cpp03/services/daytime_client.cpp b/asio/src/examples/cpp03/services/daytime_client.cpp
index f915465..0d5c249 100644
--- a/asio/src/examples/cpp03/services/daytime_client.cpp
+++ b/asio/src/examples/cpp03/services/daytime_client.cpp
@@ -64,8 +64,8 @@
 
     // Resolve the address corresponding to the given host.
     asio::ip::tcp::resolver resolver(io_service);
-    asio::ip::tcp::resolver::query query(argv[1], "daytime");
-    asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(query);
+    asio::ip::tcp::resolver::results_type endpoints =
+      resolver.resolve(argv[1], "daytime");
 
     // Start an asynchronous connect.
     debug_stream_socket socket(io_service);
diff --git a/asio/src/examples/cpp03/socks4/sync_client.cpp b/asio/src/examples/cpp03/socks4/sync_client.cpp
index feea82a..86dd3ab 100644
--- a/asio/src/examples/cpp03/socks4/sync_client.cpp
+++ b/asio/src/examples/cpp03/socks4/sync_client.cpp
@@ -35,8 +35,7 @@
 
     // Get a list of endpoints corresponding to the SOCKS 4 server name.
     tcp::resolver resolver(io_service);
-    tcp::resolver::query socks_query(argv[1], argv[2]);
-    tcp::resolver::results_type endpoints = resolver.resolve(socks_query);
+    tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
 
     // Try each endpoint until we successfully establish a connection to the
     // SOCKS 4 server.
@@ -45,8 +44,8 @@
 
     // Get an endpoint for the Boost website. This will be passed to the SOCKS
     // 4 server. Explicitly specify IPv4 since SOCKS 4 does not support IPv6.
-    tcp::resolver::query http_query(tcp::v4(), "www.boost.org", "http");
-    tcp::endpoint http_endpoint = *resolver.resolve(http_query);
+    tcp::endpoint http_endpoint =
+      *resolver.resolve(tcp::v4(), "www.boost.org", "http").begin();
 
     // Send the request to the SOCKS 4 server.
     socks4::request socks_request(
diff --git a/asio/src/examples/cpp03/ssl/client.cpp b/asio/src/examples/cpp03/ssl/client.cpp
index 5c2fa7a..037ee0d 100644
--- a/asio/src/examples/cpp03/ssl/client.cpp
+++ b/asio/src/examples/cpp03/ssl/client.cpp
@@ -137,9 +137,8 @@
     asio::io_service io_service;
 
     asio::ip::tcp::resolver resolver(io_service);
-    asio::ip::tcp::resolver::query query(argv[1], argv[2]);
     asio::ip::tcp::resolver::results_type endpoints =
-      resolver.resolve(query);
+      resolver.resolve(argv[1], argv[2]);
 
     asio::ssl::context ctx(asio::ssl::context::sslv23);
     ctx.load_verify_file("ca.pem");
diff --git a/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp b/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp
index ff7ec13..9f9054b 100644
--- a/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp
+++ b/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp
@@ -293,7 +293,7 @@
     tcp::resolver r(io_service);
     client c(io_service);
 
-    c.start(r.resolve(tcp::resolver::query(argv[1], argv[2])));
+    c.start(r.resolve(argv[1], argv[2]));
 
     io_service.run();
   }
diff --git a/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp b/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp
index 3ad630d..005a33f 100644
--- a/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp
+++ b/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp
@@ -71,9 +71,8 @@
       boost::posix_time::time_duration timeout)
   {
     // Resolve the host name and service to a list of endpoints.
-    tcp::resolver::query query(host, service);
     tcp::resolver::results_type endpoints =
-      tcp::resolver(io_service_).resolve(query);
+      tcp::resolver(io_service_).resolve(host, service);
 
     // Set a deadline for the asynchronous operation. As a host name may
     // resolve to multiple endpoints, this function uses the composed operation
diff --git a/asio/src/examples/cpp03/tutorial/daytime1/client.cpp b/asio/src/examples/cpp03/tutorial/daytime1/client.cpp
index 2d3c64f..4ab212c 100644
--- a/asio/src/examples/cpp03/tutorial/daytime1/client.cpp
+++ b/asio/src/examples/cpp03/tutorial/daytime1/client.cpp
@@ -27,8 +27,8 @@
     asio::io_service io_service;
 
     tcp::resolver resolver(io_service);
-    tcp::resolver::query query(argv[1], "daytime");
-    tcp::resolver::results_type endpoints = resolver.resolve(query);
+    tcp::resolver::results_type endpoints =
+      resolver.resolve(argv[1], "daytime");
 
     tcp::socket socket(io_service);
     asio::connect(socket, endpoints);
diff --git a/asio/src/examples/cpp03/tutorial/daytime4/client.cpp b/asio/src/examples/cpp03/tutorial/daytime4/client.cpp
index 7607e86..a906382 100644
--- a/asio/src/examples/cpp03/tutorial/daytime4/client.cpp
+++ b/asio/src/examples/cpp03/tutorial/daytime4/client.cpp
@@ -27,8 +27,8 @@
     asio::io_service io_service;
 
     udp::resolver resolver(io_service);
-    udp::resolver::query query(udp::v4(), argv[1], "daytime");
-    udp::endpoint receiver_endpoint = *resolver.resolve(query);
+    udp::endpoint receiver_endpoint =
+      *resolver.resolve(udp::v4(), argv[1], "daytime").begin();
 
     udp::socket socket(io_service);
     socket.open(udp::v4());
diff --git a/asio/src/examples/cpp11/chat/chat_client.cpp b/asio/src/examples/cpp11/chat/chat_client.cpp
index 8163038..bfc37e3 100644
--- a/asio/src/examples/cpp11/chat/chat_client.cpp
+++ b/asio/src/examples/cpp11/chat/chat_client.cpp
@@ -140,8 +140,8 @@
     asio::io_service io_service;
 
     tcp::resolver resolver(io_service);
-    auto endpoint_iterator = resolver.resolve({ argv[1], argv[2] });
-    chat_client c(io_service, endpoint_iterator);
+    auto endpoints = resolver.resolve(argv[1], argv[2]);
+    chat_client c(io_service, endpoints);
 
     std::thread t([&io_service](){ io_service.run(); });
 
diff --git a/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp b/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp
index 7f60d31..cdcd3b5 100644
--- a/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp
+++ b/asio/src/examples/cpp11/echo/blocking_tcp_echo_client.cpp
@@ -31,7 +31,7 @@
 
     tcp::socket s(io_service);
     tcp::resolver resolver(io_service);
-    asio::connect(s, resolver.resolve({argv[1], argv[2]}));
+    asio::connect(s, resolver.resolve(argv[1], argv[2]));
 
     std::cout << "Enter message: ";
     char request[max_length];
diff --git a/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp b/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp
index 76e49ba..d02c59a 100644
--- a/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp
+++ b/asio/src/examples/cpp11/echo/blocking_udp_echo_client.cpp
@@ -32,7 +32,7 @@
     udp::socket s(io_service, udp::endpoint(udp::v4(), 0));
 
     udp::resolver resolver(io_service);
-    udp::endpoint endpoint = *resolver.resolve({udp::v4(), argv[1], argv[2]});
+    udp::endpoint endpoint = *resolver.resolve(udp::v4(), argv[1], argv[2]);
 
     std::cout << "Enter message: ";
     char request[max_length];
diff --git a/asio/src/examples/cpp11/futures/daytime_client.cpp b/asio/src/examples/cpp11/futures/daytime_client.cpp
index 0d40052..6a1ecd3 100644
--- a/asio/src/examples/cpp11/futures/daytime_client.cpp
+++ b/asio/src/examples/cpp11/futures/daytime_client.cpp
@@ -24,20 +24,20 @@
   {
     udp::resolver resolver(io_service);
 
-    std::future<udp::resolver::results_type> iter =
+    std::future<udp::resolver::results_type> endpoints =
       resolver.async_resolve(
-          {udp::v4(), hostname, "daytime"},
+          udp::v4(), hostname, "daytime",
           asio::use_future);
 
-    // The async_resolve operation above returns the endpoint iterator as a
-    // future value that is not retrieved ...
+    // The async_resolve operation above returns the endpoints as a future
+    // value that is not retrieved ...
 
     udp::socket socket(io_service, udp::v4());
 
     std::array<char, 1> send_buf  = {{ 0 }};
     std::future<std::size_t> send_length =
       socket.async_send_to(asio::buffer(send_buf),
-          *iter.get(), // ... until here. This call may block.
+          *endpoints.get().begin(), // ... until here. This call may block.
           asio::use_future);
 
     // Do other things here while the send completes.
diff --git a/asio/src/examples/cpp11/http/server/server.cpp b/asio/src/examples/cpp11/http/server/server.cpp
index 9114792..5a9a415 100644
--- a/asio/src/examples/cpp11/http/server/server.cpp
+++ b/asio/src/examples/cpp11/http/server/server.cpp
@@ -36,7 +36,8 @@
 
   // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
   asio::ip::tcp::resolver resolver(io_service_);
-  asio::ip::tcp::endpoint endpoint = *resolver.resolve({address, port});
+  asio::ip::tcp::endpoint endpoint =
+    *resolver.resolve(address, port).begin();
   acceptor_.open(endpoint.protocol());
   acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true));
   acceptor_.bind(endpoint);
diff --git a/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp b/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp
index 7f60d31..cdcd3b5 100644
--- a/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp
+++ b/asio/src/examples/cpp14/echo/blocking_tcp_echo_client.cpp
@@ -31,7 +31,7 @@
 
     tcp::socket s(io_service);
     tcp::resolver resolver(io_service);
-    asio::connect(s, resolver.resolve({argv[1], argv[2]}));
+    asio::connect(s, resolver.resolve(argv[1], argv[2]));
 
     std::cout << "Enter message: ";
     char request[max_length];
diff --git a/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp b/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp
index fa15059..678099e 100644
--- a/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp
+++ b/asio/src/examples/cpp14/echo/blocking_udp_echo_client.cpp
@@ -33,7 +33,8 @@
     udp::socket s(io_service, udp::endpoint(udp::v4(), 0));
 
     udp::resolver resolver(io_service);
-    udp::endpoint endpoint = *resolver.resolve({udp::v4(), argv[1], argv[2]});
+    udp::endpoint endpoint =
+      *resolver.resolve(udp::v4(), argv[1], argv[2]).begin();
 
     std::cout << "Enter message: ";
     char request[max_length];
diff --git a/asio/src/tests/unit/ip/icmp.cpp b/asio/src/tests/unit/ip/icmp.cpp
index b8cc2e8..5606995 100644
--- a/asio/src/tests/unit/ip/icmp.cpp
+++ b/asio/src/tests/unit/ip/icmp.cpp
@@ -415,10 +415,17 @@
 
 namespace ip_icmp_resolver_compile {
 
-void resolve_handler(const asio::error_code&,
-    asio::ip::icmp::resolver::iterator)
+struct resolve_handler
 {
-}
+  resolve_handler() {}
+  void operator()(const asio::error_code&,
+      asio::ip::icmp::resolver::results_type) {}
+#if defined(ASIO_HAS_MOVE)
+  resolve_handler(resolve_handler&&) {}
+private:
+  resolve_handler(const resolve_handler&);
+#endif // defined(ASIO_HAS_MOVE)
+};
 
 void test()
 {
@@ -446,25 +453,72 @@
 
     resolver.cancel();
 
-    ip::icmp::resolver::iterator iter1 = resolver.resolve(q);
-    (void)iter1;
+    ip::icmp::resolver::results_type results1 = resolver.resolve(q);
+    (void)results1;
 
-    ip::icmp::resolver::iterator iter2 = resolver.resolve(q, ec);
-    (void)iter2;
+    ip::icmp::resolver::results_type results2 = resolver.resolve(q, ec);
+    (void)results2;
 
-    ip::icmp::resolver::iterator iter3 = resolver.resolve(e);
-    (void)iter3;
+    ip::icmp::resolver::results_type results3 = resolver.resolve("", "");
+    (void)results3;
 
-    ip::icmp::resolver::iterator iter4 = resolver.resolve(e, ec);
-    (void)iter4;
+    ip::icmp::resolver::results_type results4 = resolver.resolve("", "", ec);
+    (void)results4;
 
-    resolver.async_resolve(q, &resolve_handler);
+    ip::icmp::resolver::results_type results5 =
+      resolver.resolve("", "", ip::icmp::resolver::flags());
+    (void)results5;
+
+    ip::icmp::resolver::results_type results6 =
+      resolver.resolve("", "", ip::icmp::resolver::flags(), ec);
+    (void)results6;
+
+    ip::icmp::resolver::results_type results7 =
+      resolver.resolve(ip::icmp::v4(), "", "");
+    (void)results7;
+
+    ip::icmp::resolver::results_type results8 =
+      resolver.resolve(ip::icmp::v4(), "", "", ec);
+    (void)results8;
+
+    ip::icmp::resolver::results_type results9 =
+      resolver.resolve(ip::icmp::v4(), "", "", ip::icmp::resolver::flags());
+    (void)results9;
+
+    ip::icmp::resolver::results_type results10 =
+      resolver.resolve(ip::icmp::v4(), "", "", ip::icmp::resolver::flags(), ec);
+    (void)results10;
+
+    ip::icmp::resolver::results_type results11 = resolver.resolve(e);
+    (void)results11;
+
+    ip::icmp::resolver::results_type results12 = resolver.resolve(e, ec);
+    (void)results12;
+
+    resolver.async_resolve(q, resolve_handler());
     int i1 = resolver.async_resolve(q, lazy);
     (void)i1;
 
-    resolver.async_resolve(e, &resolve_handler);
-    int i2 = resolver.async_resolve(e, lazy);
+    resolver.async_resolve(q, resolve_handler());
+    int i2 = resolver.async_resolve("", "", lazy);
     (void)i2;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i3 = resolver.async_resolve("", "", ip::icmp::resolver::flags(), lazy);
+    (void)i3;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i4 = resolver.async_resolve(ip::icmp::v4(), "", "", lazy);
+    (void)i4;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i5 = resolver.async_resolve(ip::icmp::v4(),
+        "", "", ip::icmp::resolver::flags(), lazy);
+    (void)i5;
+
+    resolver.async_resolve(e, resolve_handler());
+    int i6 = resolver.async_resolve(e, lazy);
+    (void)i6;
   }
   catch (std::exception&)
   {
diff --git a/asio/src/tests/unit/ip/tcp.cpp b/asio/src/tests/unit/ip/tcp.cpp
index f20a385..cec36b7 100644
--- a/asio/src/tests/unit/ip/tcp.cpp
+++ b/asio/src/tests/unit/ip/tcp.cpp
@@ -994,25 +994,72 @@
 
     resolver.cancel();
 
-    ip::tcp::resolver::results_type iter1 = resolver.resolve(q);
-    (void)iter1;
+    ip::tcp::resolver::results_type results1 = resolver.resolve(q);
+    (void)results1;
 
-    ip::tcp::resolver::results_type iter2 = resolver.resolve(q, ec);
-    (void)iter2;
+    ip::tcp::resolver::results_type results2 = resolver.resolve(q, ec);
+    (void)results2;
 
-    ip::tcp::resolver::results_type iter3 = resolver.resolve(e);
-    (void)iter3;
+    ip::tcp::resolver::results_type results3 = resolver.resolve("", "");
+    (void)results3;
 
-    ip::tcp::resolver::results_type iter4 = resolver.resolve(e, ec);
-    (void)iter4;
+    ip::tcp::resolver::results_type results4 = resolver.resolve("", "", ec);
+    (void)results4;
+
+    ip::tcp::resolver::results_type results5 =
+      resolver.resolve("", "", ip::tcp::resolver::flags());
+    (void)results5;
+
+    ip::tcp::resolver::results_type results6 =
+      resolver.resolve("", "", ip::tcp::resolver::flags(), ec);
+    (void)results6;
+
+    ip::tcp::resolver::results_type results7 =
+      resolver.resolve(ip::tcp::v4(), "", "");
+    (void)results7;
+
+    ip::tcp::resolver::results_type results8 =
+      resolver.resolve(ip::tcp::v4(), "", "", ec);
+    (void)results8;
+
+    ip::tcp::resolver::results_type results9 =
+      resolver.resolve(ip::tcp::v4(), "", "", ip::tcp::resolver::flags());
+    (void)results9;
+
+    ip::tcp::resolver::results_type results10 =
+      resolver.resolve(ip::tcp::v4(), "", "", ip::tcp::resolver::flags(), ec);
+    (void)results10;
+
+    ip::tcp::resolver::results_type results11 = resolver.resolve(e);
+    (void)results11;
+
+    ip::tcp::resolver::results_type results12 = resolver.resolve(e, ec);
+    (void)results12;
 
     resolver.async_resolve(q, resolve_handler());
     int i1 = resolver.async_resolve(q, lazy);
     (void)i1;
 
-    resolver.async_resolve(e, resolve_handler());
-    int i2 = resolver.async_resolve(e, lazy);
+    resolver.async_resolve(q, resolve_handler());
+    int i2 = resolver.async_resolve("", "", lazy);
     (void)i2;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i3 = resolver.async_resolve("", "", ip::tcp::resolver::flags(), lazy);
+    (void)i3;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i4 = resolver.async_resolve(ip::tcp::v4(), "", "", lazy);
+    (void)i4;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i5 = resolver.async_resolve(ip::tcp::v4(),
+        "", "", ip::tcp::resolver::flags(), lazy);
+    (void)i5;
+
+    resolver.async_resolve(e, resolve_handler());
+    int i6 = resolver.async_resolve(e, lazy);
+    (void)i6;
   }
   catch (std::exception&)
   {
diff --git a/asio/src/tests/unit/ip/udp.cpp b/asio/src/tests/unit/ip/udp.cpp
index 7e28ffa..9ee2f9b 100644
--- a/asio/src/tests/unit/ip/udp.cpp
+++ b/asio/src/tests/unit/ip/udp.cpp
@@ -550,25 +550,72 @@
 
     resolver.cancel();
 
-    ip::udp::resolver::results_type iter1 = resolver.resolve(q);
-    (void)iter1;
+    ip::udp::resolver::results_type results1 = resolver.resolve(q);
+    (void)results1;
 
-    ip::udp::resolver::results_type iter2 = resolver.resolve(q, ec);
-    (void)iter2;
+    ip::udp::resolver::results_type results2 = resolver.resolve(q, ec);
+    (void)results2;
 
-    ip::udp::resolver::results_type iter3 = resolver.resolve(e);
-    (void)iter3;
+    ip::udp::resolver::results_type results3 = resolver.resolve("", "");
+    (void)results3;
 
-    ip::udp::resolver::results_type iter4 = resolver.resolve(e, ec);
-    (void)iter4;
+    ip::udp::resolver::results_type results4 = resolver.resolve("", "", ec);
+    (void)results4;
+
+    ip::udp::resolver::results_type results5 =
+      resolver.resolve("", "", ip::udp::resolver::flags());
+    (void)results5;
+
+    ip::udp::resolver::results_type results6 =
+      resolver.resolve("", "", ip::udp::resolver::flags(), ec);
+    (void)results6;
+
+    ip::udp::resolver::results_type results7 =
+      resolver.resolve(ip::udp::v4(), "", "");
+    (void)results7;
+
+    ip::udp::resolver::results_type results8 =
+      resolver.resolve(ip::udp::v4(), "", "", ec);
+    (void)results8;
+
+    ip::udp::resolver::results_type results9 =
+      resolver.resolve(ip::udp::v4(), "", "", ip::udp::resolver::flags());
+    (void)results9;
+
+    ip::udp::resolver::results_type results10 =
+      resolver.resolve(ip::udp::v4(), "", "", ip::udp::resolver::flags(), ec);
+    (void)results10;
+
+    ip::udp::resolver::results_type results11 = resolver.resolve(e);
+    (void)results11;
+
+    ip::udp::resolver::results_type results12 = resolver.resolve(e, ec);
+    (void)results12;
 
     resolver.async_resolve(q, resolve_handler());
     int i1 = resolver.async_resolve(q, lazy);
     (void)i1;
 
-    resolver.async_resolve(e, resolve_handler());
-    int i2 = resolver.async_resolve(e, lazy);
+    resolver.async_resolve(q, resolve_handler());
+    int i2 = resolver.async_resolve("", "", lazy);
     (void)i2;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i3 = resolver.async_resolve("", "", ip::udp::resolver::flags(), lazy);
+    (void)i3;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i4 = resolver.async_resolve(ip::udp::v4(), "", "", lazy);
+    (void)i4;
+
+    resolver.async_resolve(q, resolve_handler());
+    int i5 = resolver.async_resolve(ip::udp::v4(),
+        "", "", ip::udp::resolver::flags(), lazy);
+    (void)i5;
+
+    resolver.async_resolve(e, resolve_handler());
+    int i6 = resolver.async_resolve(e, lazy);
+    (void)i6;
   }
   catch (std::exception&)
   {