Replicate C++ docs from master to beta branch

Original PR #3074 by @dgquintas
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
index 605fb7f..923c8ff 100644
--- a/examples/cpp/helloworld/greeter_async_client.cc
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -35,13 +35,8 @@
 #include <memory>
 #include <string>
 
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/security/credentials.h>
+#include <grpc++/grpc++.h>
+
 #include "helloworld.grpc.pb.h"
 
 using grpc::Channel;
@@ -58,39 +53,72 @@
   explicit GreeterClient(std::shared_ptr<Channel> channel)
       : stub_(Greeter::NewStub(channel)) {}
 
+  // Assambles the client's payload, sends it and presents the response back
+  // from the server.
   std::string SayHello(const std::string& user) {
+    // Data we are sending to the server.
     HelloRequest request;
     request.set_name(user);
+
+    // Container for the data we expect from the server.
     HelloReply reply;
+
+    // Context for the client. It could be used to convey extra information to
+    // the server and/or tweak certain RPC behaviors.
     ClientContext context;
+
+    // The producer-consumer queue we use to communicate asynchronously with the
+    // gRPC runtime.
     CompletionQueue cq;
+
+    // Storage for the status of the RPC upon completion.
     Status status;
 
+    // stub_->AsyncSayHello() perform the RPC call, returning an instance we
+    // store in "rpc". Because we are using the asynchronous API, we need the
+    // hold on to the "rpc" instance in order to get updates on the ongoig RPC.
     std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
         stub_->AsyncSayHello(&context, request, &cq));
+
+    // Request that, upon completion of the RPC, "reply" be updated with the
+    // server's response; "status" with the indication of whether the operation
+    // was successful. Tag the request with the integer 1.
     rpc->Finish(&reply, &status, (void*)1);
     void* got_tag;
     bool ok = false;
+    // Block until the next result is available in the completion queue "cq".
     cq.Next(&got_tag, &ok);
-    GPR_ASSERT(ok);
-    GPR_ASSERT(got_tag == (void*)1);
 
+    // Verify that the result from "cq" corresponds, by its tag, our previous
+    // request.
+    GPR_ASSERT(got_tag == (void*)1);
+    // ... and that the request was completed successfully. Note that "ok"
+    // corresponds solely to the request for updates introduced by Finish().
+    GPR_ASSERT(ok);
+
+    // Act upon the status of the actual RPC.
     if (status.ok()) {
       return reply.message();
     } else {
-      return "Rpc failed";
+      return "RPC failed";
     }
   }
 
  private:
+  // Out of the passed in Channel comes the stub, stored here, our view of the
+  // server's exposed services.
   std::unique_ptr<Greeter::Stub> stub_;
 };
 
 int main(int argc, char** argv) {
-  GreeterClient greeter(grpc::CreateChannel(
-      "localhost:50051", grpc::InsecureCredentials()));
+  // Instantiate the client. It requires a channel, out of which the actual RPCs
+  // are created. This channel models a connection to an endpoint (in this case,
+  // localhost at port 50051). We indicate that the channel isn't authenticated
+  // (use of InsecureCredentials()).
+  GreeterClient greeter(
+      grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
   std::string user("world");
-  std::string reply = greeter.SayHello(user);
+  std::string reply = greeter.SayHello(user);  // The actual RPC call!
   std::cout << "Greeter received: " << reply << std::endl;
 
   return 0;
diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc
index 189c3af..b2047a8 100644
--- a/examples/cpp/helloworld/greeter_async_server.cc
+++ b/examples/cpp/helloworld/greeter_async_server.cc
@@ -36,13 +36,8 @@
 #include <string>
 #include <thread>
 
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
+#include <grpc++/grpc++.h>
+
 #include "helloworld.grpc.pb.h"
 
 using grpc::Server;
@@ -59,6 +54,7 @@
  public:
   ~ServerImpl() {
     server_->Shutdown();
+    // Always shutdown the completion queue after the server.
     cq_->Shutdown();
   }
 
@@ -67,56 +63,102 @@
     std::string server_address("0.0.0.0:50051");
 
     ServerBuilder builder;
+    // Listen on the given address without any authentication mechanism.
     builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+    // Register "service_" as the instance through which we'll communicate with
+    // clients. In this case it corresponds to an *asynchronous* service.
     builder.RegisterAsyncService(&service_);
+    // Get hold of the completion queue used for the asynchronous communication
+    // with the gRPC runtime.
     cq_ = builder.AddCompletionQueue();
+    // Finally assemble the server.
     server_ = builder.BuildAndStart();
     std::cout << "Server listening on " << server_address << std::endl;
 
+    // Proceed to the server's main loop.
     HandleRpcs();
   }
 
  private:
+  // Class encompasing the state and logic needed to serve a request.
   class CallData {
    public:
+    // Take in the "service" instance (in this case representing an asynchronous
+    // server) and the completion queue "cq" used for asynchronous communication
+    // with the gRPC runtime.
     CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq)
         : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) {
+      // Invoke the serving logic right away.
       Proceed();
     }
 
     void Proceed() {
       if (status_ == CREATE) {
+        // As part of the initial CREATE state, we *request* that the system
+        // start processing SayHello requests. In this request, "this" acts are
+        // the tag uniquely identifying the request (so that different CallData
+        // instances can serve different requests concurrently), in this case
+        // the memory address of this CallData instance.
         service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
                                   this);
+        // Make this instance progress to the PROCESS state.
         status_ = PROCESS;
       } else if (status_ == PROCESS) {
+        // Spawn a new CallData instance to serve new clients while we process
+        // the one for this CallData. The instance will deallocate itself as
+        // part of its FINISH state.
         new CallData(service_, cq_);
+
+        // The actual processing.
         std::string prefix("Hello ");
         reply_.set_message(prefix + request_.name());
+
+        // And we are done! Let the gRPC runtime know we've finished, using the
+        // memory address of this instance as the uniquely identifying tag for
+        // the event.
         responder_.Finish(reply_, Status::OK, this);
         status_ = FINISH;
       } else {
+        GPR_ASSERT(status_ == FINISH);
+        // Once in the FINISH state, deallocate ourselves (CallData).
         delete this;
       }
     }
 
    private:
+    // The means of communication with the gRPC runtime for an asynchronous
+    // server.
     Greeter::AsyncService* service_;
+    // The producer-consumer queue where for asynchronous server notifications.
     ServerCompletionQueue* cq_;
+    // Context for the rpc, allowing to tweak aspects of it such as the use
+    // of compression, authentication, as well as to send metadata back to the
+    // client.
     ServerContext ctx_;
+
+    // What we get from the client.
     HelloRequest request_;
+    // What we send back to the client.
     HelloReply reply_;
+
+    // The means to get back to the client.
     ServerAsyncResponseWriter<HelloReply> responder_;
+
+    // Let's implement a tiny state machine with the following states.
     enum CallStatus { CREATE, PROCESS, FINISH };
-    CallStatus status_;
+    CallStatus status_;  // The current serving state.
   };
 
   // This can be run in multiple threads if needed.
   void HandleRpcs() {
+    // Spawn a new CallData instance to serve new clients.
     new CallData(&service_, cq_.get());
-    void* tag;
+    void* tag;  // uniquely identifies a request.
     bool ok;
     while (true) {
+      // Block waiting to read the next event from the completion queue. The
+      // event is uniquely identified by its tag, which in this case is the
+      // memory address of a CallData instance.
       cq_->Next(&tag, &ok);
       GPR_ASSERT(ok);
       static_cast<CallData*>(tag)->Proceed();
diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc
index bfb7c12..6cd8353 100644
--- a/examples/cpp/helloworld/greeter_client.cc
+++ b/examples/cpp/helloworld/greeter_client.cc
@@ -35,11 +35,8 @@
 #include <memory>
 #include <string>
 
-#include <grpc/grpc.h>
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/security/credentials.h>
+#include <grpc++/grpc++.h>
+
 #include "helloworld.grpc.pb.h"
 
 using grpc::Channel;
@@ -54,17 +51,28 @@
   GreeterClient(std::shared_ptr<Channel> channel)
       : stub_(Greeter::NewStub(channel)) {}
 
+  // Assambles the client's payload, sends it and presents the response back
+  // from the server.
   std::string SayHello(const std::string& user) {
+    // Data we are sending to the server.
     HelloRequest request;
     request.set_name(user);
+
+    // Container for the data we expect from the server.
     HelloReply reply;
+
+    // Context for the client. It could be used to convey extra information to
+    // the server and/or tweak certain RPC behaviors.
     ClientContext context;
 
+    // The actual RPC.
     Status status = stub_->SayHello(&context, request, &reply);
+
+    // Act upon its status.
     if (status.ok()) {
       return reply.message();
     } else {
-      return "Rpc failed";
+      return "RPC failed";
     }
   }
 
@@ -73,6 +81,10 @@
 };
 
 int main(int argc, char** argv) {
+  // Instantiate the client. It requires a channel, out of which the actual RPCs
+  // are created. This channel models a connection to an endpoint (in this case,
+  // localhost at port 50051). We indicate that the channel isn't authenticated
+  // (use of InsecureCredentials()).
   GreeterClient greeter(
       grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
   std::string user("world");
diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc
index b434752..9eab32c 100644
--- a/examples/cpp/helloworld/greeter_server.cc
+++ b/examples/cpp/helloworld/greeter_server.cc
@@ -35,11 +35,8 @@
 #include <memory>
 #include <string>
 
-#include <grpc/grpc.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
+#include <grpc++/grpc++.h>
+
 #include "helloworld.grpc.pb.h"
 
 using grpc::Server;
@@ -50,6 +47,7 @@
 using helloworld::HelloReply;
 using helloworld::Greeter;
 
+// Logic and data behind the server's behavior.
 class GreeterServiceImpl final : public Greeter::Service {
   Status SayHello(ServerContext* context, const HelloRequest* request,
                   HelloReply* reply) override {
@@ -64,10 +62,17 @@
   GreeterServiceImpl service;
 
   ServerBuilder builder;
+  // Listen on the given address without any authentication mechanism.
   builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+  // Register "service" as the instance through which we'll communicate with
+  // clients. In this case it corresponds to an *synchronous* service.
   builder.RegisterService(&service);
+  // Finally assemble the server.
   std::unique_ptr<Server> server(builder.BuildAndStart());
   std::cout << "Server listening on " << server_address << std::endl;
+
+  // Wait for the server to shutdown. Note that some other thread must be
+  // responsible for shutting down the server for this call to ever return.
   server->Wait();
 }
 
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index a8af741..60c816d 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -65,18 +65,19 @@
 template <class R>
 class ClientAsyncResponseReader;
 
+/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
 class Channel GRPC_FINAL : public GrpcLibrary,
                            public CallHook,
                            public std::enable_shared_from_this<Channel> {
  public:
   ~Channel();
 
-  // Get the current channel state. If the channel is in IDLE and try_to_connect
-  // is set to true, try to connect.
+  /// Get the current channel state. If the channel is in IDLE and
+  /// \a try_to_connect is set to true, try to connect.
   grpc_connectivity_state GetState(bool try_to_connect);
 
-  // Return the tag on cq when the channel state is changed or deadline expires.
-  // GetState needs to called to get the current state.
+  /// Return the \a tag on \a cq when the channel state is changed or \a
+  /// deadline expires. \a GetState needs to called to get the current state.
   template <typename T>
   void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
                            CompletionQueue* cq, void* tag) {
@@ -84,8 +85,8 @@
     NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
   }
 
-  // Blocking wait for channel state change or deadline expiration.
-  // GetState needs to called to get the current state.
+  /// Blocking wait for channel state change or \a deadline expiration.
+  /// \a GetState needs to called to get the current state.
   template <typename T>
   bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
     TimePoint<T> deadline_tp(deadline);
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 917a122..7046f93 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -31,6 +31,21 @@
  *
  */
 
+/// A ClientContext allows the person implementing a service client to:
+///
+/// - Add custom metadata key-value pairs that will propagated to the server
+/// side.
+/// - Control call settings such as compression and authentication.
+/// - Initial and trailing metadata coming from the server.
+/// - Get performance metrics (ie, census).
+///
+/// Context settings are only relevant to the call they are invoked with, that
+/// is to say, they aren't sticky. Some of these settings, such as the
+/// compression options, can be made persistant at channel construction time
+/// (see \a grpc::CreateCustomChannel).
+///
+/// \warning ClientContext instances should \em not be reused across rpcs.
+
 #ifndef GRPCXX_CLIENT_CONTEXT_H
 #define GRPCXX_CLIENT_CONTEXT_H
 
@@ -72,6 +87,11 @@
 class ClientAsyncResponseReader;
 class ServerContext;
 
+/// Options for \a ClientContext::FromServerContext specifying which traits from
+/// the \a ServerContext to propagate (copy) from it into a new \a
+/// ClientContext.
+///
+/// \see ClientContext::FromServerContext
 class PropagationOptions {
  public:
   PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
@@ -131,26 +151,66 @@
   ClientContext();
   ~ClientContext();
 
-  /// Create a new ClientContext that propagates some or all of its attributes
+  /// Create a new \a ClientContext as a child of an incoming server call,
+  /// according to \a options (\see PropagationOptions).
+  ///
+  /// \param server_context The source server context to use as the basis for
+  /// constructing the client context.
+  /// \param options The options controlling what to copy from the \a
+  /// server_context.
+  ///
+  /// \return A newly constructed \a ClientContext instance based on \a
+  /// server_context, with traits propagated (copied) according to \a options.
   static std::unique_ptr<ClientContext> FromServerContext(
       const ServerContext& server_context,
       PropagationOptions options = PropagationOptions());
 
+  /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
+  /// a client call. These are made available at the server side by the \a
+  /// grpc::ServerContext::client_metadata() method.
+  ///
+  /// \warning This method should only be called before invoking the rpc.
+  ///
+  /// \param meta_key The metadata key. If \a meta_value is binary data, it must
+  /// end in "-bin".
+  /// \param meta_value The metadata value. If its value is binary, it must be
+  /// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a
+  /// meta_key must end in "-bin".
   void AddMetadata(const grpc::string& meta_key,
                    const grpc::string& meta_value);
 
+  /// Return a collection of initial metadata key-value pairs. Note that keys
+  /// may happen more than once (ie, a \a std::multimap is returned).
+  ///
+  /// \warning This method should only be called after initial metadata has been
+  /// received. For streaming calls, see \a
+  /// ClientReaderInterface::WaitForInitialMetadata().
+  ///
+  /// \return A multimap of initial metadata key-value pairs from the server.
   const std::multimap<grpc::string_ref, grpc::string_ref>&
   GetServerInitialMetadata() {
     GPR_ASSERT(initial_metadata_received_);
     return recv_initial_metadata_;
   }
 
+  /// Return a collection of trailing metadata key-value pairs. Note that keys
+  /// may happen more than once (ie, a \a std::multimap is returned).
+  ///
+  /// \warning This method is only callable once the stream has finished.
+  ///
+  /// \return A multimap of metadata trailing key-value pairs from the server.
   const std::multimap<grpc::string_ref, grpc::string_ref>&
   GetServerTrailingMetadata() {
     // TODO(yangg) check finished
     return trailing_metadata_;
   }
 
+  /// Set the deadline for the client call.
+  ///
+  /// \warning This method should only be called before invoking the rpc.
+  ///
+  /// \param deadline the deadline for the client call. Units are determined by
+  /// the type used.
   template <typename T>
   void set_deadline(const T& deadline) {
     TimePoint<T> deadline_tp(deadline);
@@ -158,40 +218,65 @@
   }
 
 #ifndef GRPC_CXX0X_NO_CHRONO
+  /// Return the deadline for the client call.
   std::chrono::system_clock::time_point deadline() {
     return Timespec2Timepoint(deadline_);
   }
 #endif  // !GRPC_CXX0X_NO_CHRONO
 
+  /// Return a \a gpr_timespec representation of the client call's deadline.
   gpr_timespec raw_deadline() { return deadline_; }
 
+  /// Set the per call authority header (see
+  /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
   void set_authority(const grpc::string& authority) { authority_ = authority; }
 
-  // Set credentials for the rpc.
+  /// Return the authentication context for this client call.
+  ///
+  /// \see grpc::AuthContext.
+  std::shared_ptr<const AuthContext> auth_context() const;
+
+  /// Set credentials for the client call.
+  ///
+  /// A credentials object encapsulates all the state needed by a client to
+  /// authenticate with a server and make various assertions, e.g., about the
+  /// client’s identity, role, or whether it is authorized to make a particular
+  /// call.
+  ///
+  /// \see  https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
   void set_credentials(const std::shared_ptr<Credentials>& creds) {
     creds_ = creds;
   }
 
+  /// Return the compression algorithm to be used by the client call.
   grpc_compression_algorithm compression_algorithm() const {
     return compression_algorithm_;
   }
 
+  /// Set \a algorithm to be the compression algorithm used for the client call.
+  ///
+  /// \param algorith The compression algorithm used for the client call.
   void set_compression_algorithm(grpc_compression_algorithm algorithm);
 
-  std::shared_ptr<const AuthContext> auth_context() const;
-
-  // Return the peer uri in a string.
-  // WARNING: this value is never authenticated or subject to any security
-  // related code. It must not be used for any authentication related
-  // functionality. Instead, use auth_context.
+  /// Return the peer uri in a string.
+  ///
+  /// \warning This value is never authenticated or subject to any security
+  /// related code. It must not be used for any authentication related
+  /// functionality. Instead, use auth_context.
+  ///
+  /// \return The call's peer URI.
   grpc::string peer() const;
 
-  // Get and set census context
+  /// Get and set census context
   void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
   struct census_context* census_context() const {
     return census_context_;
   }
 
+  /// Send a best-effort out-of-band cancel. The call could be in any stage.
+  /// e.g. if it is already finished, it may still return success.
+  ///
+  /// There is no guarantee the call will be cancelled.
   void TryCancel();
 
  private:
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index d81d2e7..0ea9704 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -31,6 +31,8 @@
  *
  */
 
+/// A completion queue implements a concurrent producer-consumer queue, with two
+/// main methods, \a Next and \a AsyncNext.
 #ifndef GRPCXX_COMPLETION_QUEUE_H
 #define GRPCXX_COMPLETION_QUEUE_H
 
@@ -67,53 +69,79 @@
 
 class Channel;
 class ClientContext;
+class CompletionQueueTag;
 class CompletionQueue;
 class RpcMethod;
 class Server;
 class ServerBuilder;
 class ServerContext;
 
-class CompletionQueueTag {
- public:
-  virtual ~CompletionQueueTag() {}
-  // Called prior to returning from Next(), return value
-  // is the status of the operation (return status is the default thing
-  // to do)
-  // If this function returns false, the tag is dropped and not returned
-  // from the completion queue
-  virtual bool FinalizeResult(void** tag, bool* status) = 0;
-};
-
-// grpc_completion_queue wrapper class
+/// A thin wrapper around \a grpc_completion_queue (see / \a
+/// src/core/surface/completion_queue.h).
 class CompletionQueue : public GrpcLibrary {
  public:
+  /// Default constructor. Implicitly creates a \a grpc_completion_queue
+  /// instance.
   CompletionQueue();
+
+  /// Wrap \a take, taking ownership of the instance.
+  ///
+  /// \param take The completion queue instance to wrap. Ownership is taken.
   explicit CompletionQueue(grpc_completion_queue* take);
+
+  /// Destructor. Destroys the owned wrapped completion queue / instance.
   ~CompletionQueue() GRPC_OVERRIDE;
 
-  // Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT
-  enum NextStatus { SHUTDOWN, GOT_EVENT, TIMEOUT };
+  /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
+  enum NextStatus {
+    SHUTDOWN,   ///< The completion queue has been shutdown.
+    GOT_EVENT,  ///< Got a new event; \a tag will be filled in with its
+                ///< associated value; \a ok indicating its success.
+    TIMEOUT     ///< deadline was reached.
+  };
 
-  // Nonblocking (until deadline) read from queue.
-  // Cannot rely on result of tag or ok if return is TIMEOUT
+  /// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
+  /// Both \a tag and \a ok are updated upon success (if an event is available
+  /// within the \a deadline).  A \a tag points to an arbitrary location usually
+  /// employed to uniquely identify an event.
+  ///
+  /// \param tag[out] Upon sucess, updated to point to the event's tag.
+  /// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
+  /// \param deadline[in] How long to block in wait for an event.
+  ///
+  /// \return The type of event read.
   template <typename T>
   NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
     TimePoint<T> deadline_tp(deadline);
     return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
   }
 
-  // Blocking read from queue.
-  // Returns false if the queue is ready for destruction, true if event
-
+  /// Read from the queue, blocking until an event is available or the queue is
+  /// shutting down.
+  ///
+  /// \param tag[out] Updated to point to the read event's tag.
+  /// \param ok[out] true if read a regular event, false otherwise.
+  ///
+  /// \return true if read a regular event, false if the queue is shutting down.
   bool Next(void** tag, bool* ok) {
     return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) !=
             SHUTDOWN);
   }
 
-  // Shutdown has to be called, and the CompletionQueue can only be
-  // destructed when false is returned from Next().
+  /// Request the shutdown of the queue.
+  ///
+  /// \warning This method must be called at some point. Once invoked, \a Next
+  /// will start to return false and \a AsyncNext will return \a
+  /// NextStatus::SHUTDOWN. Only once either one of these methods does that
+  /// (that is, once the queue has been \em drained) can an instance of this
+  /// class be destroyed.
   void Shutdown();
 
+  /// Returns a \em raw pointer to the underlying \a grpc_completion_queue
+  /// instance.
+  ///
+  /// \warning Remember that the returned instance is owned. No transfer of
+  /// owership is performed.
   grpc_completion_queue* cq() { return cq_; }
 
  private:
@@ -150,16 +178,29 @@
 
   NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
 
-  // Wraps grpc_completion_queue_pluck.
-  // Cannot be mixed with calls to Next().
+  /// Wraps \a grpc_completion_queue_pluck.
+  /// \warning Must not be mixed with calls to \a Next.
   bool Pluck(CompletionQueueTag* tag);
 
-  // Does a single polling pluck on tag
+  /// Performs a single polling pluck on \a tag.
   void TryPluck(CompletionQueueTag* tag);
 
   grpc_completion_queue* cq_;  // owned
 };
 
+/// An interface allowing implementors to process and filter event tags.
+class CompletionQueueTag {
+ public:
+  virtual ~CompletionQueueTag() {}
+  // Called prior to returning from Next(), return value is the status of the
+  // operation (return status is the default thing to do). If this function
+  // returns false, the tag is dropped and not returned from the completion
+  // queue
+  virtual bool FinalizeResult(void** tag, bool* status) = 0;
+};
+
+/// A specific type of completion queue used by the processing of notifications
+/// by servers. Instantiated by \a ServerBuilder.
 class ServerCompletionQueue : public CompletionQueue {
  private:
   friend class ServerBuilder;
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 72f0517..196d292 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -42,13 +42,24 @@
 
 namespace grpc {
 
-// If creds does not hold an object or is invalid, a lame channel is returned.
+/// Create a new \a Channel pointing to \a target
+///
+/// \param target The URI of the endpoint to connect to.
+/// \param creds Credentials to use for the created channel. If it does not hold
+/// an object or is invalid, a lame channel is returned.
+/// \param args Options for channel creation.
 std::shared_ptr<Channel> CreateChannel(
     const grpc::string& target, const std::shared_ptr<Credentials>& creds);
 
-// For advanced use and testing ONLY. Override default channel arguments only
-// if necessary.
-// If creds does not hold an object or is invalid, a lame channel is returned.
+/// Create a new \em custom \a Channel pointing to \a target
+///
+/// \warning For advanced use and testing ONLY. Override default channel
+/// arguments only if necessary.
+///
+/// \param target The URI of the endpoint to connect to.
+/// \param creds Credentials to use for the created channel. If it does not hold
+/// an object or is invalid, a lame channel is returned.
+/// \param args Options for channel creation.
 std::shared_ptr<Channel> CreateCustomChannel(
     const grpc::string& target, const std::shared_ptr<Credentials>& creds,
     const ChannelArguments& args);
diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h
new file mode 100644
index 0000000..b7d5fb0
--- /dev/null
+++ b/include/grpc++/grpc++.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/// \mainpage gRPC C++ API
+///
+/// The gRPC C++ API mainly consists of the following classes:
+/// - grpc::Channel, which represents the connection to an endpoint. See [the
+/// gRPC Concepts page](http://www.grpc.io/docs/guides/concepts.html) for more
+/// details. Channels are created by the factory function grpc::CreateChannel.
+/// - grpc::CompletionQueue, the producer-consumer queue used for all
+/// asynchronous communication with the gRPC runtime.
+/// - grpc::ClientContext and grpc::ServerContext, where optional configuration
+/// for an RPC can be set, such as setting custom metadata to be conveyed to the
+/// peer, compression settings, authentication, etc.
+/// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder.
+///
+/// Refer to the
+/// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp)
+/// for code putting these pieces into play.
+
+#ifndef GRPCXX_GRPCXX_H
+#define GRPCXX_GRPCXX_H
+
+#include <grpc/grpc.h>
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/completion_queue.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+
+#endif  // GRPCXX_GRPCXX_H
diff --git a/include/grpc++/security/auth_context.h b/include/grpc++/security/auth_context.h
index fc2701e..4b1bbd8 100644
--- a/include/grpc++/security/auth_context.h
+++ b/include/grpc++/security/auth_context.h
@@ -37,6 +37,7 @@
 #include <iterator>
 #include <vector>
 
+#include <grpc/grpc_security.h>
 #include <grpc++/support/config.h>
 #include <grpc++/support/string_ref.h>
 
@@ -73,26 +74,41 @@
   const char* name_;
 };
 
+/// Class encapsulating the Authentication Information.
+///
+/// It includes the secure identity of the peer, the type of secure transport
+/// used as well as any other properties required by the authorization layer.
 class AuthContext {
  public:
   virtual ~AuthContext() {}
 
-  // Returns true if the peer is authenticated.
+  /// Returns true if the peer is authenticated.
   virtual bool IsPeerAuthenticated() const = 0;
 
-  // A peer identity, in general is one or more properties (in which case they
-  // have the same name).
+  /// A peer identity.
+  ///
+  /// It is, in general, comprised of one or more properties (in which case they
+  /// have the same name).
   virtual std::vector<grpc::string_ref> GetPeerIdentity() const = 0;
   virtual grpc::string GetPeerIdentityPropertyName() const = 0;
 
-  // Returns all the property values with the given name.
+  /// Returns all the property values with the given name.
   virtual std::vector<grpc::string_ref> FindPropertyValues(
       const grpc::string& name) const = 0;
 
-  // Iteration over all the properties.
+  /// Iteration over all the properties.
   virtual AuthPropertyIterator begin() const = 0;
   virtual AuthPropertyIterator end() const = 0;
 
+  static string transport_security_type_property_name() {
+    return GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME;
+  }
+  static string ssl_transport_security_type() {
+    return GRPC_SSL_TRANSPORT_SECURITY_TYPE;
+  }
+  static string x509_cn_property_name() { return GRPC_X509_CN_PROPERTY_NAME; }
+  static string x509_san_property_name() { return GRPC_X509_SAN_PROPERTY_NAME; }
+
   // Mutation functions: should only be used by an AuthMetadataProcessor.
   virtual void AddProperty(const grpc::string& key,
                            const grpc::string_ref& value) = 0;
diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h
index ce5a9e0..e423849 100644
--- a/include/grpc++/security/credentials.h
+++ b/include/grpc++/security/credentials.h
@@ -44,9 +44,17 @@
 class Channel;
 class SecureCredentials;
 
+/// A credentials object encapsulates all the state needed by a client to
+/// authenticate with a server and make various assertions, e.g., about the
+/// client’s identity, role, or whether it is authorized to make a particular
+/// call.
+///
+/// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
 class Credentials : public GrpcLibrary {
  public:
   ~Credentials() GRPC_OVERRIDE;
+
+  /// Apply this instance's credentials to \a call.
   virtual bool ApplyToCall(grpc_call* call) = 0;
 
  protected:
@@ -65,68 +73,96 @@
       const grpc::string& target, const ChannelArguments& args) = 0;
 };
 
-// Options used to build SslCredentials
-// pem_roots_cert is the buffer containing the PEM encoding of the server root
-// certificates. If this parameter is empty, the default roots will be used.
-// pem_private_key is the buffer containing the PEM encoding of the client's
-// private key. This parameter can be empty if the client does not have a
-// private key.
-// pem_cert_chain is the buffer containing the PEM encoding of the client's
-// certificate chain. This parameter can be empty if the client does not have
-// a certificate chain.
+/// Options used to build SslCredentials.
 struct SslCredentialsOptions {
+  /// The buffer containing the PEM encoding of the server root certificates. If
+  /// this parameter is empty, the default roots will be used.  The default
+  /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
+  /// environment variable pointing to a file on the file system containing the
+  /// roots.
   grpc::string pem_root_certs;
+
+  /// The buffer containing the PEM encoding of the client's private key. This
+  /// parameter can be empty if the client does not have a private key.
   grpc::string pem_private_key;
+
+  /// The buffer containing the PEM encoding of the client's certificate chain.
+  /// This parameter can be empty if the client does not have a certificate
+  /// chain.
   grpc::string pem_cert_chain;
 };
 
-// Factories for building different types of Credentials
-// The functions may return empty shared_ptr when credentials cannot be created.
-// If a Credentials pointer is returned, it can still be invalid when used to
-// create a channel. A lame channel will be created then and all rpcs will
-// fail on it.
+// Factories for building different types of Credentials The functions may
+// return empty shared_ptr when credentials cannot be created. If a
+// Credentials pointer is returned, it can still be invalid when used to create
+// a channel. A lame channel will be created then and all rpcs will fail on it.
 
-// Builds credentials with reasonable defaults.
+/// Builds credentials with reasonable defaults.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
 std::shared_ptr<Credentials> GoogleDefaultCredentials();
 
-// Builds SSL Credentials given SSL specific options
+/// Builds SSL Credentials given SSL specific options
 std::shared_ptr<Credentials> SslCredentials(
     const SslCredentialsOptions& options);
 
-// Builds credentials for use when running in GCE
+/// Builds credentials for use when running in GCE
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
 std::shared_ptr<Credentials> GoogleComputeEngineCredentials();
 
-// Builds Service Account JWT Access credentials.
-// json_key is the JSON key string containing the client's private key.
-// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
-// (JWT) created with this credentials. It should not exceed
-// grpc_max_auth_token_lifetime or will be cropped to this value.
+/// Builds Service Account JWT Access credentials.
+/// json_key is the JSON key string containing the client's private key.
+/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
+/// (JWT) created with this credentials. It should not exceed
+/// grpc_max_auth_token_lifetime or will be cropped to this value.
 std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
     const grpc::string& json_key, long token_lifetime_seconds);
 
-// Builds refresh token credentials.
-// json_refresh_token is the JSON string containing the refresh token along
-// with a client_id and client_secret.
+/// Builds refresh token credentials.
+/// json_refresh_token is the JSON string containing the refresh token along
+/// with a client_id and client_secret.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
 std::shared_ptr<Credentials> GoogleRefreshTokenCredentials(
     const grpc::string& json_refresh_token);
 
-// Builds access token credentials.
-// access_token is an oauth2 access token that was fetched using an out of band
-// mechanism.
+/// Builds access token credentials.
+/// access_token is an oauth2 access token that was fetched using an out of band
+/// mechanism.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
 std::shared_ptr<Credentials> AccessTokenCredentials(
     const grpc::string& access_token);
 
-// Builds IAM credentials.
+/// Builds IAM credentials.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
 std::shared_ptr<Credentials> GoogleIAMCredentials(
     const grpc::string& authorization_token,
     const grpc::string& authority_selector);
 
-// Combines two credentials objects into a composite credentials
+/// Combines two credentials objects into a composite credentials
 std::shared_ptr<Credentials> CompositeCredentials(
     const std::shared_ptr<Credentials>& creds1,
     const std::shared_ptr<Credentials>& creds2);
 
-// Credentials for an unencrypted, unauthenticated channel
+/// Credentials for an unencrypted, unauthenticated channel
 std::shared_ptr<Credentials> InsecureCredentials();
 
 }  // namespace grpc
diff --git a/include/grpc++/security/server_credentials.h b/include/grpc++/security/server_credentials.h
index 2094c74..e933825 100644
--- a/include/grpc++/security/server_credentials.h
+++ b/include/grpc++/security/server_credentials.h
@@ -45,7 +45,7 @@
 namespace grpc {
 class Server;
 
-// grpc_server_credentials wrapper class.
+// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
 class ServerCredentials {
  public:
   virtual ~ServerCredentials();
@@ -58,11 +58,16 @@
  private:
   friend class ::grpc::Server;
 
+  /// Tries to bind \a server to the given \a addr (eg, localhost:1234,
+  /// 192.168.1.1:31416, [::1]:27182, etc.)
+  ///
+  /// \return bound port number on sucess, 0 on failure.
+  // TODO(dgq): the "port" part seems to be a misnomer.
   virtual int AddPortToServer(const grpc::string& addr,
                               grpc_server* server) = 0;
 };
 
-// Options to create ServerCredentials with SSL
+/// Options to create ServerCredentials with SSL
 struct SslServerCredentialsOptions {
   SslServerCredentialsOptions() : force_client_auth(false) {}
 
@@ -75,10 +80,11 @@
   bool force_client_auth;
 };
 
-// Builds SSL ServerCredentials given SSL specific options
+/// Builds SSL ServerCredentials given SSL specific options
 std::shared_ptr<ServerCredentials> SslServerCredentials(
     const SslServerCredentialsOptions& options);
 
+/// Builds insecure server credentials.
 std::shared_ptr<ServerCredentials> InsecureServerCredentials();
 
 }  // namespace grpc
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 22d14ee..18a8017 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -57,24 +57,30 @@
 class ServerAsyncStreamingInterface;
 class ThreadPoolInterface;
 
-// Currently it only supports handling rpcs in a single thread.
+/// Models a gRPC server.
+///
+/// Servers are configured and started via \a grpc::ServerBuilder.
 class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
  public:
   ~Server();
 
-  // Shutdown the server, block until all rpc processing finishes.
-  // Forcefully terminate pending calls after deadline expires.
+  /// Shutdown the server, blocking until all rpc processing finishes.
+  /// Forcefully terminate pending calls after \a deadline expires.
+  ///
+  /// \param deadline How long to wait until pending rpcs are forcefully
+  /// terminated.
   template <class T>
   void Shutdown(const T& deadline) {
     ShutdownInternal(TimePoint<T>(deadline).raw_time());
   }
 
-  // Shutdown the server, waiting for all rpc processing to finish.
+  /// Shutdown the server, waiting for all rpc processing to finish.
   void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
 
-  // Block waiting for all work to complete (the server must either
-  // be shutting down or some other thread must call Shutdown for this
-  // function to ever return)
+  /// Block waiting for all work to complete.
+  ///
+  /// \warning The server must be either shutting down or some other thread must
+  /// call \a Shutdown for this function to ever return.
   void Wait();
 
  private:
@@ -86,22 +92,57 @@
   class AsyncRequest;
   class ShutdownRequest;
 
-  // ServerBuilder use only
+  /// Server constructors. To be used by \a ServerBuilder only.
+  ///
+  /// \param thread_pool The threadpool instance to use for call processing.
+  /// \param thread_pool_owned Does the server own the \a thread_pool instance?
+  /// \param max_message_size Maximum message length that the channel can
+  /// receive.
   Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
          int max_message_size);
-  // Register a service. This call does not take ownership of the service.
-  // The service must exist for the lifetime of the Server instance.
+
+  /// Register a service. This call does not take ownership of the service.
+  /// The service must exist for the lifetime of the Server instance.
   bool RegisterService(const grpc::string* host, RpcService* service);
+
+  /// Register an asynchronous service. This call does not take ownership of the
+  /// service. The service must exist for the lifetime of the Server instance.
   bool RegisterAsyncService(const grpc::string* host,
                             AsynchronousService* service);
+
+  /// Register a generic service. This call does not take ownership of the
+  /// service. The service must exist for the lifetime of the Server instance.
   void RegisterAsyncGenericService(AsyncGenericService* service);
-  // Add a listening port. Can be called multiple times.
+
+  /// Tries to bind \a server to the given \a addr.
+  ///
+  /// It can be invoked multiple times.
+  ///
+  /// \param addr The address to try to bind to the server (eg, localhost:1234,
+  /// 192.168.1.1:31416, [::1]:27182, etc.).
+  /// \params creds The credentials associated with the server.
+  ///
+  /// \return bound port number on sucess, 0 on failure.
+  ///
+  /// \warning It's an error to call this method on an already started server.
   int AddListeningPort(const grpc::string& addr, ServerCredentials* creds);
-  // Start the server.
+
+  /// Start the server.
+  ///
+  /// \param cqs Completion queues for handling asynchronous services. The
+  /// caller is required to keep all completion queues live until the server is
+  /// destroyed.
+  /// \param num_cqs How many completion queues does \a cqs hold.
+  ///
+  /// \return true on a successful shutdown.
   bool Start(ServerCompletionQueue** cqs, size_t num_cqs);
 
   void HandleQueueClosed();
+
+  /// Process one or more incoming calls.
   void RunRpc();
+
+  /// Schedule \a RunRpc to run in the threadpool.
   void ScheduleCallback();
 
   void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 8cd2048..496e786 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -51,57 +51,68 @@
 class SynchronousService;
 class ThreadPoolInterface;
 
+/// A builder class for the creation and startup of \a grpc::Server instances.
 class ServerBuilder {
  public:
   ServerBuilder();
 
-  // Register a service. This call does not take ownership of the service.
-  // The service must exist for the lifetime of the Server instance returned by
-  // BuildAndStart().
-  // Matches requests with any :authority
+  /// Register a service. This call does not take ownership of the service.
+  /// The service must exist for the lifetime of the \a Server instance returned
+  /// by \a BuildAndStart().
+  /// Matches requests with any :authority
   void RegisterService(SynchronousService* service);
 
-  // Register an asynchronous service.
-  // This call does not take ownership of the service or completion queue.
-  // The service and completion queuemust exist for the lifetime of the Server
-  // instance returned by BuildAndStart().
-  // Matches requests with any :authority
+  /// Register an asynchronous service.
+  /// This call does not take ownership of the service or completion queue.
+  /// The service and completion queuemust exist for the lifetime of the \a
+  /// Server instance returned by \a BuildAndStart().
+  /// Matches requests with any :authority
   void RegisterAsyncService(AsynchronousService* service);
 
-  // Register a generic service.
-  // Matches requests with any :authority
+  /// Register a generic service.
+  /// Matches requests with any :authority
   void RegisterAsyncGenericService(AsyncGenericService* service);
 
-  // Register a service. This call does not take ownership of the service.
-  // The service must exist for the lifetime of the Server instance returned by
-  // BuildAndStart().
-  // Only matches requests with :authority \a host
+  /// Register a service. This call does not take ownership of the service.
+  /// The service must exist for the lifetime of the \a Server instance returned
+  /// by BuildAndStart().
+  /// Only matches requests with :authority \a host
   void RegisterService(const grpc::string& host, SynchronousService* service);
 
-  // Register an asynchronous service.
-  // This call does not take ownership of the service or completion queue.
-  // The service and completion queuemust exist for the lifetime of the Server
-  // instance returned by BuildAndStart().
-  // Only matches requests with :authority \a host
+  /// Register an asynchronous service.
+  /// This call does not take ownership of the service or completion queue.
+  /// The service and completion queuemust exist for the lifetime of the \a
+  /// Server instance returned by \a BuildAndStart().
+  /// Only matches requests with :authority equal to \a host
   void RegisterAsyncService(const grpc::string& host,
                             AsynchronousService* service);
 
-  // Set max message size in bytes.
+  /// Set max message size in bytes.
   void SetMaxMessageSize(int max_message_size) {
     max_message_size_ = max_message_size;
   }
 
-  // Add a listening port. Can be called multiple times.
+  /// Tries to bind \a server to the given \a addr.
+  ///
+  /// It can be invoked multiple times.
+  ///
+  /// \param addr The address to try to bind to the server (eg, localhost:1234,
+  /// 192.168.1.1:31416, [::1]:27182, etc.).
+  /// \params creds The credentials associated with the server.
+  /// \param selected_port[out] Upon success, updated to contain the port
+  /// number. \a nullptr otherwise.
+  ///
+  // TODO(dgq): the "port" part seems to be a misnomer.
   void AddListeningPort(const grpc::string& addr,
                         std::shared_ptr<ServerCredentials> creds,
                         int* selected_port = nullptr);
 
-  // Add a completion queue for handling asynchronous services
-  // Caller is required to keep this completion queue live until
-  // the server is destroyed.
+  /// Add a completion queue for handling asynchronous services
+  /// Caller is required to keep this completion queue live until
+  /// the server is destroyed.
   std::unique_ptr<ServerCompletionQueue> AddCompletionQueue();
 
-  // Return a running server which is ready for processing rpcs.
+  /// Return a running server which is ready for processing calls.
   std::unique_ptr<Server> BuildAndStart();
 
  private:
diff --git a/include/grpc++/support/async_stream.h b/include/grpc++/support/async_stream.h
index 4c12fda..b4dae30 100644
--- a/include/grpc++/support/async_stream.h
+++ b/include/grpc++/support/async_stream.h
@@ -45,32 +45,48 @@
 
 namespace grpc {
 
-// Async interfaces
-// Common interface for all client side streaming.
+/// Common interface for all client side asynchronous streaming.
 class ClientAsyncStreamingInterface {
  public:
   virtual ~ClientAsyncStreamingInterface() {}
 
+  /// Request notification of the reading of the initial metadata. Completion
+  /// will be notified by \a tag on the associated completion queue.
+  ///
+  /// \param[in] tag Tag identifying this request.
   virtual void ReadInitialMetadata(void* tag) = 0;
 
+  /// Request notification completion.
+  ///
+  /// \param[out] status To be updated with the operation status.
+  /// \param[in] tag Tag identifying this request.
   virtual void Finish(Status* status, void* tag) = 0;
 };
 
-// An interface that yields a sequence of R messages.
+/// An interface that yields a sequence of messages of type \a R.
 template <class R>
 class AsyncReaderInterface {
  public:
   virtual ~AsyncReaderInterface() {}
 
+  /// Read a message of type \a R into \a msg. Completion will be notified by \a
+  /// tag on the associated completion queue.
+  ///
+  /// \param[out] msg Where to eventually store the read message.
+  /// \param[in] tag The tag identifying the operation.
   virtual void Read(R* msg, void* tag) = 0;
 };
 
-// An interface that can be fed a sequence of W messages.
+/// An interface that can be fed a sequence of messages of type \a W.
 template <class W>
 class AsyncWriterInterface {
  public:
   virtual ~AsyncWriterInterface() {}
 
+  /// Request the writing of \a msg with identifying tag \a tag.
+  ///
+  /// \param[in] msg The message to be written.
+  /// \param[in] tag The tag identifying the operation.
   virtual void Write(const W& msg, void* tag) = 0;
 };
 
@@ -81,7 +97,7 @@
 template <class R>
 class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
  public:
-  // Create a stream and write the first request out.
+  /// Create a stream and write the first request out.
   template <class W>
   ClientAsyncReader(Channel* channel, CompletionQueue* cq,
                     const RpcMethod& method, ClientContext* context,
@@ -131,10 +147,14 @@
   CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
 };
 
+/// Common interface for client side asynchronous writing.
 template <class W>
 class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
                                    public AsyncWriterInterface<W> {
  public:
+  /// Signal the client is done with the writes.
+  ///
+  /// \param[in] tag The tag identifying the operation.
   virtual void WritesDone(void* tag) = 0;
 };
 
@@ -194,12 +214,15 @@
             CallOpClientRecvStatus> finish_ops_;
 };
 
-// Client-side interface for bi-directional streaming.
+/// Client-side interface for asynchronous bi-directional streaming.
 template <class W, class R>
 class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
                                          public AsyncWriterInterface<W>,
                                          public AsyncReaderInterface<R> {
  public:
+  /// Signal the client is done with the writes.
+  ///
+  /// \param[in] tag The tag identifying the operation.
   virtual void WritesDone(void* tag) = 0;
 };
 
@@ -373,7 +396,7 @@
   CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
 };
 
-// Server-side interface for bi-directional streaming.
+/// Server-side interface for asynchronous bi-directional streaming.
 template <class W, class R>
 class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
                                            public AsyncWriterInterface<W>,
diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h
index 3f8cc25..c413703 100644
--- a/include/grpc++/support/byte_buffer.h
+++ b/include/grpc++/support/byte_buffer.h
@@ -46,21 +46,24 @@
 
 namespace grpc {
 
+/// A sequence of bytes.
 class ByteBuffer GRPC_FINAL {
  public:
+  /// Constuct an empty buffer.
   ByteBuffer() : buffer_(nullptr) {}
 
+  /// Construct buffer from \a slices, of which there are \a nslices.
   ByteBuffer(const Slice* slices, size_t nslices);
 
-  ~ByteBuffer() {
-    if (buffer_) {
-      grpc_byte_buffer_destroy(buffer_);
-    }
-  }
+  ~ByteBuffer();
 
+  /// Dump (read) the buffer contents into \a slices.
   void Dump(std::vector<Slice>* slices) const;
 
+  /// Remove all data.
   void Clear();
+
+  /// Buffer size in bytes.
   size_t Length() const;
 
  private:
@@ -78,6 +81,7 @@
     buffer_ = buf;
   }
 
+  // For \a SerializationTraits's usage.
   grpc_byte_buffer* buffer() const { return buffer_; }
 
   grpc_byte_buffer* buffer_;
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index cee6846..9957712 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -46,9 +46,9 @@
 class ChannelArgumentsTest;
 }  // namespace testing
 
-// Options for channel creation. The user can use generic setters to pass
-// key value pairs down to c channel creation code. For grpc related options,
-// concrete setters are provided.
+/// Options for channel creation. The user can use generic setters to pass
+/// key value pairs down to c channel creation code. For grpc related options,
+/// concrete setters are provided.
 class ChannelArguments {
  public:
   ChannelArguments() {}
@@ -62,21 +62,26 @@
 
   void Swap(ChannelArguments& other);
 
-  // grpc specific channel argument setters
-  // Set target name override for SSL host name checking.
+  /// Populates this instance with the arguments from \a channel_args. Does not
+  /// take ownership of \a channel_args.
+  ///
+  /// Note that the underlying arguments are shared. Changes made to either \a
+  /// channel_args or this instance would be reflected on both.
+  void SetChannelArgs(grpc_channel_args* channel_args) const;
+
+  // gRPC specific channel argument setters
+  /// Set target name override for SSL host name checking.
   void SetSslTargetNameOverride(const grpc::string& name);
   // TODO(yangg) add flow control options
-
-  // Set the compression algorithm for the channel.
+  /// Set the compression algorithm for the channel.
   void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
 
   // Generic channel argument setters. Only for advanced use cases.
+  /// Set an integer argument \a value under \a key.
   void SetInt(const grpc::string& key, int value);
+  /// Set a textual argument \a value under \a key.
   void SetString(const grpc::string& key, const grpc::string& value);
 
-  // Populates given channel_args with args_, does not take ownership.
-  void SetChannelArgs(grpc_channel_args* channel_args) const;
-
  private:
   friend class SecureCredentials;
   friend class testing::ChannelArgumentsTest;
diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h
index b2343a7..456379c 100644
--- a/include/grpc++/support/slice.h
+++ b/include/grpc++/support/slice.h
@@ -39,28 +39,42 @@
 
 namespace grpc {
 
+/// A wrapper around \a grpc_slice.
+///
+/// A slice represents a contiguous reference counted array of bytes.
+/// It is cheap to take references to a slice, and it is cheap to create a
+/// slice pointing to a subset of another slice.
 class Slice GRPC_FINAL {
  public:
-  // construct empty slice
+  /// Construct an empty slice.
   Slice();
-  // destructor - drops one ref
+  // Destructor - drops one reference.
   ~Slice();
-  // construct slice from grpc slice, adding a ref
+
   enum AddRef { ADD_REF };
+  /// Construct a slice from \a slice, adding a reference.
   Slice(gpr_slice slice, AddRef);
-  // construct slice from grpc slice, stealing a ref
+
   enum StealRef { STEAL_REF };
+  /// Construct a slice from \a slice, stealing a reference.
   Slice(gpr_slice slice, StealRef);
-  // copy constructor - adds a ref
+
+  /// Copy constructor, adds a reference.
   Slice(const Slice& other);
-  // assignment - ref count is unchanged
+
+  /// Assignment, reference count is unchanged.
   Slice& operator=(Slice other) {
     std::swap(slice_, other.slice_);
     return *this;
   }
 
+  /// Byte size.
   size_t size() const { return GPR_SLICE_LENGTH(slice_); }
+
+  /// Raw pointer to the beginning (first element) of the slice.
   const gpr_uint8* begin() const { return GPR_SLICE_START_PTR(slice_); }
+
+  /// Raw pointer to the end (one byte \em past the last element) of the slice.
   const gpr_uint8* end() const { return GPR_SLICE_END_PTR(slice_); }
 
  private:
diff --git a/include/grpc++/support/status.h b/include/grpc++/support/status.h
index 05750ff..e59bac9 100644
--- a/include/grpc++/support/status.h
+++ b/include/grpc++/support/status.h
@@ -39,19 +39,31 @@
 
 namespace grpc {
 
+/// Did it work? If it didn't, why?
+///
+/// See \a grpc::StatusCode for details on the available code and their meaning.
 class Status {
  public:
+  /// Construct an OK instance.
   Status() : code_(StatusCode::OK) {}
+
+  /// Construct an instance with associated \a code and \a details (also
+  // referred to as "error_message").
   Status(StatusCode code, const grpc::string& details)
       : code_(code), details_(details) {}
 
   // Pre-defined special status objects.
+  /// An OK pre-defined instance.
   static const Status& OK;
+  /// A CANCELLED pre-defined instance.
   static const Status& CANCELLED;
 
+  /// Return the instance's error code.
   StatusCode error_code() const { return code_; }
+  /// Return the instance's error message.
   grpc::string error_message() const { return details_; }
 
+  /// Is the status OK?
   bool ok() const { return code_ == StatusCode::OK; }
 
  private:
diff --git a/include/grpc++/support/status_code_enum.h b/include/grpc++/support/status_code_enum.h
index 7cb4045..ee05b40 100644
--- a/include/grpc++/support/status_code_enum.h
+++ b/include/grpc++/support/status_code_enum.h
@@ -37,120 +37,113 @@
 namespace grpc {
 
 enum StatusCode {
-  /* Not an error; returned on success */
+  /// Not an error; returned on success.
   OK = 0,
 
-  /* The operation was cancelled (typically by the caller). */
+  /// The operation was cancelled (typically by the caller).
   CANCELLED = 1,
 
-  /* Unknown error.  An example of where this error may be returned is
-     if a Status value received from another address space belongs to
-     an error-space that is not known in this address space.  Also
-     errors raised by APIs that do not return enough error information
-     may be converted to this error. */
+  /// Unknown error. An example of where this error may be returned is if a
+  /// Status value received from another address space belongs to an error-space
+  /// that is not known in this address space. Also errors raised by APIs that
+  /// do not return enough error information may be converted to this error.
   UNKNOWN = 2,
 
-  /* Client specified an invalid argument.  Note that this differs
-     from FAILED_PRECONDITION.  INVALID_ARGUMENT indicates arguments
-     that are problematic regardless of the state of the system
-     (e.g., a malformed file name). */
+  /// Client specified an invalid argument. Note that this differs from
+  /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
+  /// problematic regardless of the state of the system (e.g., a malformed file
+  /// name).
   INVALID_ARGUMENT = 3,
 
-  /* Deadline expired before operation could complete.  For operations
-     that change the state of the system, this error may be returned
-     even if the operation has completed successfully.  For example, a
-     successful response from a server could have been delayed long
-     enough for the deadline to expire. */
+  /// Deadline expired before operation could complete. For operations that
+  /// change the state of the system, this error may be returned even if the
+  /// operation has completed successfully. For example, a successful response
+  /// from a server could have been delayed long enough for the deadline to
+  /// expire.
   DEADLINE_EXCEEDED = 4,
 
-  /* Some requested entity (e.g., file or directory) was not found. */
+  /// Some requested entity (e.g., file or directory) was not found.
   NOT_FOUND = 5,
 
-  /* Some entity that we attempted to create (e.g., file or directory)
-     already exists. */
+  /// Some entity that we attempted to create (e.g., file or directory) already
+  /// exists.
   ALREADY_EXISTS = 6,
 
-  /* The caller does not have permission to execute the specified
-     operation.  PERMISSION_DENIED must not be used for rejections
-     caused by exhausting some resource (use RESOURCE_EXHAUSTED
-     instead for those errors).  PERMISSION_DENIED must not be
-     used if the caller can not be identified (use UNAUTHENTICATED
-     instead for those errors). */
+  /// The caller does not have permission to execute the specified operation.
+  /// PERMISSION_DENIED must not be used for rejections caused by exhausting
+  /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
+  /// PERMISSION_DENIED must not be used if the caller can not be identified
+  /// (use UNAUTHENTICATED instead for those errors).
   PERMISSION_DENIED = 7,
 
-  /* The request does not have valid authentication credentials for the
-     operation. */
+  /// The request does not have valid authentication credentials for the
+  /// operation.
   UNAUTHENTICATED = 16,
 
-  /* Some resource has been exhausted, perhaps a per-user quota, or
-     perhaps the entire file system is out of space. */
+  /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+  /// entire file system is out of space.
   RESOURCE_EXHAUSTED = 8,
 
-  /* Operation was rejected because the system is not in a state
-     required for the operation's execution.  For example, directory
-     to be deleted may be non-empty, an rmdir operation is applied to
-     a non-directory, etc.
-
-     A litmus test that may help a service implementor in deciding
-     between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
-      (a) Use UNAVAILABLE if the client can retry just the failing call.
-      (b) Use ABORTED if the client should retry at a higher-level
-          (e.g., restarting a read-modify-write sequence).
-      (c) Use FAILED_PRECONDITION if the client should not retry until
-          the system state has been explicitly fixed.  E.g., if an "rmdir"
-          fails because the directory is non-empty, FAILED_PRECONDITION
-          should be returned since the client should not retry unless
-          they have first fixed up the directory by deleting files from it.
-      (d) Use FAILED_PRECONDITION if the client performs conditional
-          REST Get/Update/Delete on a resource and the resource on the
-          server does not match the condition. E.g., conflicting
-          read-modify-write on the same resource. */
+  /// Operation was rejected because the system is not in a state required for
+  /// the operation's execution. For example, directory to be deleted may be
+  /// non-empty, an rmdir operation is applied to a non-directory, etc.
+  ///
+  /// A litmus test that may help a service implementor in deciding
+  /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+  ///  (a) Use UNAVAILABLE if the client can retry just the failing call.
+  ///  (b) Use ABORTED if the client should retry at a higher-level
+  ///      (e.g., restarting a read-modify-write sequence).
+  ///  (c) Use FAILED_PRECONDITION if the client should not retry until
+  ///      the system state has been explicitly fixed. E.g., if an "rmdir"
+  ///      fails because the directory is non-empty, FAILED_PRECONDITION
+  ///      should be returned since the client should not retry unless
+  ///      they have first fixed up the directory by deleting files from it.
+  ///  (d) Use FAILED_PRECONDITION if the client performs conditional
+  ///      REST Get/Update/Delete on a resource and the resource on the
+  ///      server does not match the condition. E.g., conflicting
+  ///      read-modify-write on the same resource.
   FAILED_PRECONDITION = 9,
 
-  /* The operation was aborted, typically due to a concurrency issue
-     like sequencer check failures, transaction aborts, etc.
-
-     See litmus test above for deciding between FAILED_PRECONDITION,
-     ABORTED, and UNAVAILABLE. */
+  /// The operation was aborted, typically due to a concurrency issue like
+  /// sequencer check failures, transaction aborts, etc.
+  ///
+  /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+  /// and UNAVAILABLE.
   ABORTED = 10,
 
-  /* Operation was attempted past the valid range.  E.g., seeking or
-     reading past end of file.
-
-     Unlike INVALID_ARGUMENT, this error indicates a problem that may
-     be fixed if the system state changes. For example, a 32-bit file
-     system will generate INVALID_ARGUMENT if asked to read at an
-     offset that is not in the range [0,2^32-1], but it will generate
-     OUT_OF_RANGE if asked to read from an offset past the current
-     file size.
-
-     There is a fair bit of overlap between FAILED_PRECONDITION and
-     OUT_OF_RANGE.  We recommend using OUT_OF_RANGE (the more specific
-     error) when it applies so that callers who are iterating through
-     a space can easily look for an OUT_OF_RANGE error to detect when
-     they are done. */
+  /// Operation was attempted past the valid range. E.g., seeking or reading
+  /// past end of file.
+  ///
+  /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
+  /// if the system state changes. For example, a 32-bit file system will
+  /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
+  /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
+  /// an offset past the current file size.
+  ///
+  /// There is a fair bit of overlap between FAILED_PRECONDITION and
+  /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
+  /// when it applies so that callers who are iterating through a space can
+  /// easily look for an OUT_OF_RANGE error to detect when they are done.
   OUT_OF_RANGE = 11,
 
-  /* Operation is not implemented or not supported/enabled in this service. */
+  /// Operation is not implemented or not supported/enabled in this service.
   UNIMPLEMENTED = 12,
 
-  /* Internal errors.  Means some invariants expected by underlying
-     system has been broken.  If you see one of these errors,
-     something is very broken. */
+  /// Internal errors. Means some invariants expected by underlying System has
+  /// been broken. If you see one of these errors, Something is very broken.
   INTERNAL = 13,
 
-  /* The service is currently unavailable.  This is a most likely a
-     transient condition and may be corrected by retrying with
-     a backoff.
-
-     See litmus test above for deciding between FAILED_PRECONDITION,
-     ABORTED, and UNAVAILABLE. */
+  /// The service is currently unavailable. This is a most likely a transient
+  /// condition and may be corrected by retrying with a backoff.
+  ///
+  /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+  /// and UNAVAILABLE.
   UNAVAILABLE = 14,
 
-  /* Unrecoverable data loss or corruption. */
+  /// Unrecoverable data loss or corruption.
   DATA_LOSS = 15,
 
-  /* Force users to include a default branch: */
+  /// Force users to include a default branch:
   DO_NOT_USE = -1
 };
 
diff --git a/include/grpc++/support/string_ref.h b/include/grpc++/support/string_ref.h
index 2bc1fec..a17e167 100644
--- a/include/grpc++/support/string_ref.h
+++ b/include/grpc++/support/string_ref.h
@@ -41,11 +41,14 @@
 
 namespace grpc {
 
-// This class is a non owning reference to a string.
-// It should be a strict subset of the upcoming std::string_ref. See:
-// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
-// The constexpr is dropped or replaced with const for legacy compiler
-// compatibility.
+/// This class is a non owning reference to a string.
+///
+/// It should be a strict subset of the upcoming std::string_ref.
+///
+/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
+///
+/// The constexpr is dropped or replaced with const for legacy compiler
+/// compatibility.
 class string_ref {
  public:
   // types
diff --git a/include/grpc++/support/sync_stream.h b/include/grpc++/support/sync_stream.h
index b4bb637..5143633 100644
--- a/include/grpc++/support/sync_stream.h
+++ b/include/grpc++/support/sync_stream.h
@@ -45,60 +45,78 @@
 
 namespace grpc {
 
-// Common interface for all client side streaming.
+/// Common interface for all synchronous client side streaming.
 class ClientStreamingInterface {
  public:
   virtual ~ClientStreamingInterface() {}
 
-  // Wait until the stream finishes, and return the final status. When the
-  // client side declares it has no more message to send, either implicitly or
-  // by calling WritesDone, it needs to make sure there is no more message to
-  // be received from the server, either implicitly or by getting a false from
-  // a Read().
-  // This function will return either:
-  // - when all incoming messages have been read and the server has returned
-  //   status
-  // - OR when the server has returned a non-OK status
+  /// Wait until the stream finishes, and return the final status. When the
+  /// client side declares it has no more message to send, either implicitly or
+  /// by calling \a WritesDone(), it needs to make sure there is no more message
+  /// to be received from the server, either implicitly or by getting a false
+  /// from a \a Read().
+  ///
+  /// This function will return either:
+  /// - when all incoming messages have been read and the server has returned
+  ///   status.
+  /// - OR when the server has returned a non-OK status.
   virtual Status Finish() = 0;
 };
 
-// An interface that yields a sequence of R messages.
+/// An interface that yields a sequence of messages of type \a R.
 template <class R>
 class ReaderInterface {
  public:
   virtual ~ReaderInterface() {}
 
-  // Blocking read a message and parse to msg. Returns true on success.
-  // The method returns false when there will be no more incoming messages,
-  // either because the other side has called WritesDone or the stream has
-  // failed (or been cancelled).
+  /// Blocking read a message and parse to \a msg. Returns \a true on success.
+  ///
+  /// \param[out] msg The read message.
+  ///
+  /// \return \a false when there will be no more incoming messages, either
+  /// because the other side has called \a WritesDone() or the stream has failed
+  /// (or been cancelled).
   virtual bool Read(R* msg) = 0;
 };
 
-// An interface that can be fed a sequence of W messages.
+/// An interface that can be fed a sequence of messages of type \a W.
 template <class W>
 class WriterInterface {
  public:
   virtual ~WriterInterface() {}
 
-  // Blocking write msg to the stream. Returns true on success.
-  // Returns false when the stream has been closed.
+  /// Blocking write \a msg to the stream with options.
+  ///
+  /// \param msg The message to be written to the stream.
+  /// \param options Options affecting the write operation.
+  ///
+  /// \return \a true on success, \a false when the stream has been closed.
   virtual bool Write(const W& msg, const WriteOptions& options) = 0;
 
+  /// Blocking write \a msg to the stream with default options.
+  ///
+  /// \param msg The message to be written to the stream.
+  ///
+  /// \return \a true on success, \a false when the stream has been closed.
   inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
 };
 
+/// Client-side interface for streaming reads of message of type \a R.
 template <class R>
 class ClientReaderInterface : public ClientStreamingInterface,
                               public ReaderInterface<R> {
  public:
+  /// Blocking wait for initial metadata from server. The received metadata
+  /// can only be accessed after this call returns. Should only be called before
+  /// the first read. Calling this method is optional, and if it is not called
+  /// the metadata will be available in ClientContext after the first read.
   virtual void WaitForInitialMetadata() = 0;
 };
 
 template <class R>
 class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
  public:
-  // Blocking create a stream and write the first request out.
+  /// Blocking create a stream and write the first request out.
   template <class W>
   ClientReader(Channel* channel, const RpcMethod& method,
                ClientContext* context, const W& request)
@@ -113,17 +131,13 @@
     cq_.Pluck(&ops);
   }
 
-  // Blocking wait for initial metadata from server. The received metadata
-  // can only be accessed after this call returns. Should only be called before
-  // the first read. Calling this method is optional, and if it is not called
-  // the metadata will be available in ClientContext after the first read.
   void WaitForInitialMetadata() {
     GPR_ASSERT(!context_->initial_metadata_received_);
 
     CallOpSet<CallOpRecvInitialMetadata> ops;
     ops.RecvInitialMetadata(context_);
     call_.PerformOps(&ops);
-    cq_.Pluck(&ops);  // status ignored
+    cq_.Pluck(&ops);  /// status ignored
   }
 
   bool Read(R* msg) GRPC_OVERRIDE {
@@ -151,17 +165,22 @@
   Call call_;
 };
 
+/// Client-side interface for streaming writes of message of type \a W.
 template <class W>
 class ClientWriterInterface : public ClientStreamingInterface,
                               public WriterInterface<W> {
  public:
+  /// Half close writing from the client.
+  /// Block until writes are completed.
+  ///
+  /// \return Whether the writes were successful.
   virtual bool WritesDone() = 0;
 };
 
 template <class W>
 class ClientWriter : public ClientWriterInterface<W> {
  public:
-  // Blocking create a stream.
+  /// Blocking create a stream.
   template <class R>
   ClientWriter(Channel* channel, const RpcMethod& method,
                ClientContext* context, R* response)
@@ -191,7 +210,7 @@
     return cq_.Pluck(&ops);
   }
 
-  // Read the final response and wait for the final status.
+  /// Read the final response and wait for the final status.
   Status Finish() GRPC_OVERRIDE {
     Status status;
     finish_ops_.ClientRecvStatus(context_, &status);
@@ -207,20 +226,28 @@
   Call call_;
 };
 
-// Client-side interface for bi-directional streaming.
+/// Client-side interface for bi-directional streaming.
 template <class W, class R>
 class ClientReaderWriterInterface : public ClientStreamingInterface,
                                     public WriterInterface<W>,
                                     public ReaderInterface<R> {
  public:
+  /// Blocking wait for initial metadata from server. The received metadata
+  /// can only be accessed after this call returns. Should only be called before
+  /// the first read. Calling this method is optional, and if it is not called
+  /// the metadata will be available in ClientContext after the first read.
   virtual void WaitForInitialMetadata() = 0;
+
+  /// Block until writes are completed.
+  ///
+  /// \return Whether the writes were successful.
   virtual bool WritesDone() = 0;
 };
 
 template <class W, class R>
 class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
  public:
-  // Blocking create a stream.
+  /// Blocking create a stream.
   ClientReaderWriter(Channel* channel, const RpcMethod& method,
                      ClientContext* context)
       : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
@@ -230,10 +257,6 @@
     cq_.Pluck(&ops);
   }
 
-  // Blocking wait for initial metadata from server. The received metadata
-  // can only be accessed after this call returns. Should only be called before
-  // the first read. Calling this method is optional, and if it is not called
-  // the metadata will be available in ClientContext after the first read.
   void WaitForInitialMetadata() {
     GPR_ASSERT(!context_->initial_metadata_received_);
 
@@ -344,7 +367,7 @@
   ServerContext* const ctx_;
 };
 
-// Server-side interface for bi-directional streaming.
+/// Server-side interface for bi-directional streaming.
 template <class W, class R>
 class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
                                       public ReaderInterface<R> {
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index a75f356..47f3df6 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -47,11 +47,9 @@
 
 /*! \mainpage GRPC Core
  *
- * \section intro_sec The GRPC Core library is a low-level library designed
- * to be wrapped by higher level libraries.
- *
- * The top-level API is provided in grpc.h.
- * Security related functionality lives in grpc_security.h.
+ * The GRPC Core library is a low-level library designed to be wrapped by higher
+ * level libraries. The top-level API is provided in grpc.h. Security related
+ * functionality lives in grpc_security.h.
  */
 
 /** Completion Queues enable notification of the completion of asynchronous
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 8de024a..74dc09e 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -34,7 +34,7 @@
 #ifndef GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
 #define GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
 
-/* Internal API for completion channels */
+/* Internal API for completion queues */
 
 #include "src/core/iomgr/pollset.h"
 #include <grpc/grpc.h>
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc
index e46e656..755234d 100644
--- a/src/cpp/util/byte_buffer.cc
+++ b/src/cpp/util/byte_buffer.cc
@@ -45,6 +45,12 @@
   buffer_ = grpc_raw_byte_buffer_create(c_slices.data(), nslices);
 }
 
+ByteBuffer::~ByteBuffer() {
+  if (buffer_) {
+    grpc_byte_buffer_destroy(buffer_);
+  }
+}
+
 void ByteBuffer::Clear() {
   if (buffer_) {
     grpc_byte_buffer_destroy(buffer_);