Further work. Compiles. WIP
diff --git a/include/grpc/byte_buffer.h b/include/grpc/byte_buffer.h
index ffc5982..c3a3943 100644
--- a/include/grpc/byte_buffer.h
+++ b/include/grpc/byte_buffer.h
@@ -34,87 +34,6 @@
 #ifndef GRPC_BYTE_BUFFER_H
 #define GRPC_BYTE_BUFFER_H
 
-#include <grpc/compression.h>
-#include <grpc/support/slice_buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-  GRPC_BB_RAW
-  /* Future types may include GRPC_BB_PROTOBUF, etc. */
-} grpc_byte_buffer_type;
-
-struct grpc_byte_buffer {
-  void *reserved;
-  grpc_byte_buffer_type type;
-  union {
-    struct {
-      void *reserved[8];
-    } reserved;
-    struct {
-      grpc_compression_algorithm compression;
-      gpr_slice_buffer slice_buffer;
-    } raw;
-  } data;
-};
-typedef struct grpc_byte_buffer grpc_byte_buffer;
-
-/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
- *
- * Increases the reference count for all \a slices processed. The user is
- * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
-grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
-                                              size_t nslices);
-
-/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
- * \a nslices). The \a compression argument defines the compression algorithm
- * used to generate the data in \a slices.
- *
- * Increases the reference count for all \a slices processed. The user is
- * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
-grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
-    gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
-
-/** Copies input byte buffer \a bb.
- *
- * Increases the reference count of all the source slices. The user is
- * responsible for calling grpc_byte_buffer_destroy over the returned copy. */
-grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
-
-/** Returns the size of the given byte buffer, in bytes. */
-size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
-
-/** Destroys \a byte_buffer deallocating all its memory. */
-void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
-
-/** Reader for byte buffers. Iterates over slices in the byte buffer */
-struct grpc_byte_buffer_reader;
-typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
-
-/** Initialize \a reader to read over \a buffer */
-void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
-                                  grpc_byte_buffer *buffer);
-
-/** Cleanup and destroy \a reader */
-void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
-
-/** Updates \a slice with the next piece of data from from \a reader and returns
- * 1. Returns 0 at the end of the stream. Caller is responsible for calling
- * gpr_slice_unref on the result. */
-int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
-                                 gpr_slice *slice);
-
-/** Merge all data from \a reader into single slice */
-gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
-
-/** Returns a RAW byte buffer instance from the output of \a reader. */
-grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
-    grpc_byte_buffer_reader *reader);
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/byte_buffer.h>
 
 #endif /* GRPC_BYTE_BUFFER_H */
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index 31d048b..f1762ef 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -36,38 +36,13 @@
 
 #include <stdlib.h>
 
-#include <grpc/support/port_platform.h>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpc/impl/codegen/compression_types.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** To be used in channel arguments */
-#define GRPC_COMPRESSION_ALGORITHM_ARG "grpc.compression_algorithm"
-#define GRPC_COMPRESSION_ALGORITHM_STATE_ARG "grpc.compression_algorithm_state"
-
-/* The various compression algorithms supported by GRPC */
-typedef enum {
-  GRPC_COMPRESS_NONE = 0,
-  GRPC_COMPRESS_DEFLATE,
-  GRPC_COMPRESS_GZIP,
-  /* TODO(ctiller): snappy */
-  GRPC_COMPRESS_ALGORITHMS_COUNT
-} grpc_compression_algorithm;
-
-typedef enum {
-  GRPC_COMPRESS_LEVEL_NONE = 0,
-  GRPC_COMPRESS_LEVEL_LOW,
-  GRPC_COMPRESS_LEVEL_MED,
-  GRPC_COMPRESS_LEVEL_HIGH,
-  GRPC_COMPRESS_LEVEL_COUNT
-} grpc_compression_level;
-
-typedef struct grpc_compression_options {
-  uint32_t enabled_algorithms_bitset; /**< All algs are enabled by default */
-  grpc_compression_algorithm default_compression_algorithm; /**< for channel */
-} grpc_compression_options;
-
 /** Parses the first \a name_length bytes of \a name as a
  * grpc_compression_algorithm instance, updating \a algorithm. Returns 1 upon
  * success, 0 otherwise. */
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 2d012ad..6ebf2a3f 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -41,6 +41,8 @@
 #include <grpc/support/slice.h>
 #include <grpc/support/time.h>
 #include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/propagation_bits.h>
+#include <grpc/impl/codegen/grpc_types.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -53,335 +55,12 @@
  * functionality lives in grpc_security.h.
  */
 
-/** Completion Queues enable notification of the completion of asynchronous
-    actions. */
-typedef struct grpc_completion_queue grpc_completion_queue;
-
-/** An alarm associated with a completion queue. */
-typedef struct grpc_alarm grpc_alarm;
-
-/** The Channel interface allows creation of Call objects. */
-typedef struct grpc_channel grpc_channel;
-
-/** A server listens to some port and responds to request calls */
-typedef struct grpc_server grpc_server;
-
-/** A Call represents an RPC. When created, it is in a configuration state
-    allowing properties to be set until it is invoked. After invoke, the Call
-    can have messages written to it and read from it. */
-typedef struct grpc_call grpc_call;
-
-/** Type specifier for grpc_arg */
-typedef enum {
-  GRPC_ARG_STRING,
-  GRPC_ARG_INTEGER,
-  GRPC_ARG_POINTER
-} grpc_arg_type;
-
-/** A single argument... each argument has a key and a value
-
-    A note on naming keys:
-      Keys are namespaced into groups, usually grouped by library, and are
-      keys for module XYZ are named XYZ.key1, XYZ.key2, etc. Module names must
-      be restricted to the regex [A-Za-z][_A-Za-z0-9]{,15}.
-      Key names must be restricted to the regex [A-Za-z][_A-Za-z0-9]{,47}.
-
-    GRPC core library keys are prefixed by grpc.
-
-    Library authors are strongly encouraged to \#define symbolic constants for
-    their keys so that it's possible to change them in the future. */
-typedef struct {
-  grpc_arg_type type;
-  char *key;
-  union {
-    char *string;
-    int integer;
-    struct {
-      void *p;
-      void *(*copy)(void *p);
-      void (*destroy)(void *p);
-    } pointer;
-  } value;
-} grpc_arg;
-
-/** An array of arguments that can be passed around.
-
-    Used to set optional channel-level configuration.
-    These configuration options are modelled as key-value pairs as defined
-    by grpc_arg; keys are strings to allow easy backwards-compatible extension
-    by arbitrary parties.
-    All evaluation is performed at channel creation time (i.e. the values in
-    this structure need only live through the creation invocation). */
-typedef struct {
-  size_t num_args;
-  grpc_arg *args;
-} grpc_channel_args;
-
-/* Channel argument keys: */
-/** Enable census for tracing and stats collection */
-#define GRPC_ARG_ENABLE_CENSUS "grpc.census"
-/** Maximum number of concurrent incoming streams to allow on a http2
-    connection */
-#define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
-/** Maximum message length that the channel can receive */
-#define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length"
-/** Initial sequence number for http2 transports */
-#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
-  "grpc.http2.initial_sequence_number"
-/** Amount to read ahead on individual streams. Defaults to 64kb, larger
-    values can help throughput on high-latency connections.
-    NOTE: at some point we'd like to auto-tune this, and this parameter
-    will become a no-op. */
-#define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
-/** How much memory to use for hpack decoding */
-#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
-  "grpc.http2.hpack_table_size.decoder"
-/** How much memory to use for hpack encoding */
-#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
-  "grpc.http2.hpack_table_size.encoder"
-/** Default authority to pass if none specified on call construction */
-#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
-/** Primary user agent: goes at the start of the user-agent metadata
-    sent on each request */
-#define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent"
-/** Secondary user agent: goes at the end of the user-agent metadata
-    sent on each request */
-#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
-/* The caller of the secure_channel_create functions may override the target
-   name used for SSL host name checking using this channel argument which is of
-   type GRPC_ARG_STRING. This *should* be used for testing only.
-   If this argument is not specified, the name used for SSL host name checking
-   will be the target parameter (assuming that the secure channel is an SSL
-   channel). If this parameter is specified and the underlying is not an SSL
-   channel, it will just be ignored. */
-#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
-
-/** Result of a grpc call. If the caller satisfies the prerequisites of a
-    particular operation, the grpc_call_error returned will be GRPC_CALL_OK.
-    Receiving any other value listed here is an indication of a bug in the
-    caller. */
-typedef enum grpc_call_error {
-  /** everything went ok */
-  GRPC_CALL_OK = 0,
-  /** something failed, we don't know what */
-  GRPC_CALL_ERROR,
-  /** this method is not available on the server */
-  GRPC_CALL_ERROR_NOT_ON_SERVER,
-  /** this method is not available on the client */
-  GRPC_CALL_ERROR_NOT_ON_CLIENT,
-  /** this method must be called before server_accept */
-  GRPC_CALL_ERROR_ALREADY_ACCEPTED,
-  /** this method must be called before invoke */
-  GRPC_CALL_ERROR_ALREADY_INVOKED,
-  /** this method must be called after invoke */
-  GRPC_CALL_ERROR_NOT_INVOKED,
-  /** this call is already finished
-      (writes_done or write_status has already been called) */
-  GRPC_CALL_ERROR_ALREADY_FINISHED,
-  /** there is already an outstanding read/write operation on the call */
-  GRPC_CALL_ERROR_TOO_MANY_OPERATIONS,
-  /** the flags value was illegal for this call */
-  GRPC_CALL_ERROR_INVALID_FLAGS,
-  /** invalid metadata was passed to this call */
-  GRPC_CALL_ERROR_INVALID_METADATA,
-  /** invalid message was passed to this call */
-  GRPC_CALL_ERROR_INVALID_MESSAGE,
-  /** completion queue for notification has not been registered with the
-      server */
-  GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE,
-  /** this batch of operations leads to more operations than allowed */
-  GRPC_CALL_ERROR_BATCH_TOO_BIG
-} grpc_call_error;
-
-/* Write Flags: */
-/** Hint that the write may be buffered and need not go out on the wire
-    immediately. GRPC is free to buffer the message until the next non-buffered
-    write, or until writes_done, but it need not buffer completely or at all. */
-#define GRPC_WRITE_BUFFER_HINT (0x00000001u)
-/** Force compression to be disabled for a particular write
-    (start_write/add_metadata). Illegal on invoke/accept. */
-#define GRPC_WRITE_NO_COMPRESS (0x00000002u)
-/** Mask of all valid flags. */
-#define GRPC_WRITE_USED_MASK (GRPC_WRITE_BUFFER_HINT | GRPC_WRITE_NO_COMPRESS)
-
-/** A single metadata element */
-typedef struct grpc_metadata {
-  const char *key;
-  const char *value;
-  size_t value_length;
-  uint32_t flags;
-
-  /** The following fields are reserved for grpc internal use.
-      There is no need to initialize them, and they will be set to garbage
-      during calls to grpc. */
-  struct {
-    void *obfuscated[4];
-  } internal_data;
-} grpc_metadata;
-
-/** The type of completion (for grpc_event) */
-typedef enum grpc_completion_type {
-  /** Shutting down */
-  GRPC_QUEUE_SHUTDOWN,
-  /** No event before timeout */
-  GRPC_QUEUE_TIMEOUT,
-  /** Operation completion */
-  GRPC_OP_COMPLETE
-} grpc_completion_type;
-
-/** The result of an operation.
-
-    Returned by a completion queue when the operation started with tag. */
-typedef struct grpc_event {
-  /** The type of the completion. */
-  grpc_completion_type type;
-  /** non-zero if the operation was successful, 0 upon failure.
-      Only GRPC_OP_COMPLETE can succeed or fail. */
-  int success;
-  /** The tag passed to grpc_call_start_batch etc to start this operation.
-      Only GRPC_OP_COMPLETE has a tag. */
-  void *tag;
-} grpc_event;
-
-typedef struct {
-  size_t count;
-  size_t capacity;
-  grpc_metadata *metadata;
-} grpc_metadata_array;
-
 void grpc_metadata_array_init(grpc_metadata_array *array);
 void grpc_metadata_array_destroy(grpc_metadata_array *array);
 
-typedef struct {
-  char *method;
-  size_t method_capacity;
-  char *host;
-  size_t host_capacity;
-  gpr_timespec deadline;
-  void *reserved;
-} grpc_call_details;
-
 void grpc_call_details_init(grpc_call_details *details);
 void grpc_call_details_destroy(grpc_call_details *details);
 
-typedef enum {
-  /** Send initial metadata: one and only one instance MUST be sent for each
-      call, unless the call was cancelled - in which case this can be skipped.
-      This op completes after all bytes of metadata have been accepted by
-      outgoing flow control. */
-  GRPC_OP_SEND_INITIAL_METADATA = 0,
-  /** Send a message: 0 or more of these operations can occur for each call.
-      This op completes after all bytes for the message have been accepted by
-      outgoing flow control. */
-  GRPC_OP_SEND_MESSAGE,
-  /** Send a close from the client: one and only one instance MUST be sent from
-      the client, unless the call was cancelled - in which case this can be
-      skipped.
-      This op completes after all bytes for the call (including the close)
-      have passed outgoing flow control. */
-  GRPC_OP_SEND_CLOSE_FROM_CLIENT,
-  /** Send status from the server: one and only one instance MUST be sent from
-      the server unless the call was cancelled - in which case this can be
-      skipped.
-      This op completes after all bytes for the call (including the status)
-      have passed outgoing flow control. */
-  GRPC_OP_SEND_STATUS_FROM_SERVER,
-  /** Receive initial metadata: one and only one MUST be made on the client,
-      must not be made on the server.
-      This op completes after all initial metadata has been read from the
-      peer. */
-  GRPC_OP_RECV_INITIAL_METADATA,
-  /** Receive a message: 0 or more of these operations can occur for each call.
-      This op completes after all bytes of the received message have been
-      read, or after a half-close has been received on this call. */
-  GRPC_OP_RECV_MESSAGE,
-  /** Receive status on the client: one and only one must be made on the client.
-      This operation always succeeds, meaning ops paired with this operation
-      will also appear to succeed, even though they may not have. In that case
-      the status will indicate some failure.
-      This op completes after all activity on the call has completed. */
-  GRPC_OP_RECV_STATUS_ON_CLIENT,
-  /** Receive close on the server: one and only one must be made on the
-      server.
-      This op completes after the close has been received by the server. */
-  GRPC_OP_RECV_CLOSE_ON_SERVER
-} grpc_op_type;
-
-/** Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT
-   which has no arguments) */
-typedef struct grpc_op {
-  /** Operation type, as defined by grpc_op_type */
-  grpc_op_type op;
-  /** Write flags bitset for grpc_begin_messages */
-  uint32_t flags;
-  /** Reserved for future usage */
-  void *reserved;
-  union {
-    /** Reserved for future usage */
-    struct {
-      void *reserved[8];
-    } reserved;
-    struct {
-      size_t count;
-      grpc_metadata *metadata;
-    } send_initial_metadata;
-    grpc_byte_buffer *send_message;
-    struct {
-      size_t trailing_metadata_count;
-      grpc_metadata *trailing_metadata;
-      grpc_status_code status;
-      const char *status_details;
-    } send_status_from_server;
-    /** ownership of the array is with the caller, but ownership of the elements
-        stays with the call object (ie key, value members are owned by the call
-        object, recv_initial_metadata->array is owned by the caller).
-        After the operation completes, call grpc_metadata_array_destroy on this
-        value, or reuse it in a future op. */
-    grpc_metadata_array *recv_initial_metadata;
-    /** ownership of the byte buffer is moved to the caller; the caller must
-        call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
-       */
-    grpc_byte_buffer **recv_message;
-    struct {
-      /** ownership of the array is with the caller, but ownership of the
-          elements stays with the call object (ie key, value members are owned
-          by the call object, trailing_metadata->array is owned by the caller).
-          After the operation completes, call grpc_metadata_array_destroy on
-         this
-          value, or reuse it in a future op. */
-      grpc_metadata_array *trailing_metadata;
-      grpc_status_code *status;
-      /** status_details is a buffer owned by the application before the op
-          completes and after the op has completed. During the operation
-          status_details may be reallocated to a size larger than
-          *status_details_capacity, in which case *status_details_capacity will
-          be updated with the new array capacity.
-
-          Pre-allocating space:
-          size_t my_capacity = 8;
-          char *my_details = gpr_malloc(my_capacity);
-          x.status_details = &my_details;
-          x.status_details_capacity = &my_capacity;
-
-          Not pre-allocating space:
-          size_t my_capacity = 0;
-          char *my_details = NULL;
-          x.status_details = &my_details;
-          x.status_details_capacity = &my_capacity;
-
-          After the call:
-          gpr_free(my_details); */
-      char **status_details;
-      size_t *status_details_capacity;
-    } recv_status_on_client;
-    struct {
-      /** out argument, set to 1 if the call failed in any way (seen as a
-          cancellation on the server), or 0 if the call succeeded */
-      int *cancelled;
-    } recv_close_on_server;
-  } data;
-} grpc_op;
-
 /** Registers a plugin to be initialized and destroyed with the library.
 
     The \a init and \a destroy functions will be invoked as part of
@@ -392,26 +71,6 @@
     the reverse order they were initialized. */
 void grpc_register_plugin(void (*init)(void), void (*destroy)(void));
 
-/* Propagation bits: this can be bitwise or-ed to form propagation_mask for
- * grpc_call */
-/** Propagate deadline */
-#define GRPC_PROPAGATE_DEADLINE ((uint32_t)1)
-/** Propagate census context */
-#define GRPC_PROPAGATE_CENSUS_STATS_CONTEXT ((uint32_t)2)
-#define GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT ((uint32_t)4)
-/** Propagate cancellation */
-#define GRPC_PROPAGATE_CANCELLATION ((uint32_t)8)
-
-/* Default propagation mask: clients of the core API are encouraged to encode
-   deltas from this in their implementations... ie write:
-   GRPC_PROPAGATE_DEFAULTS & ~GRPC_PROPAGATE_DEADLINE to disable deadline
-   propagation. Doing so gives flexibility in the future to define new
-   propagation types that are default inherited or not. */
-#define GRPC_PROPAGATE_DEFAULTS                                                \
-  ((uint32_t)((                                                                \
-      0xffff | GRPC_PROPAGATE_DEADLINE | GRPC_PROPAGATE_CENSUS_STATS_CONTEXT | \
-      GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT | GRPC_PROPAGATE_CANCELLATION)))
-
 /** Initialize the grpc library.
 
     It is not safe to call any other grpc functions before calling this.
diff --git a/include/grpc/impl/codegen/atm.h b/include/grpc/impl/codegen/atm.h
new file mode 100644
index 0000000..5376026
--- /dev/null
+++ b/include/grpc/impl/codegen/atm.h
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_ATM_H
+#define GRPC_IMPL_CODEGEN_ATM_H
+
+/* This interface provides atomic operations and barriers.
+   It is internal to gpr support code and should not be used outside it.
+
+   If an operation with acquire semantics precedes another memory access by the
+   same thread, the operation will precede that other access as seen by other
+   threads.
+
+   If an operation with release semantics follows another memory access by the
+   same thread, the operation will follow that other access as seen by other
+   threads.
+
+   Routines with "acq" or "full" in the name have acquire semantics.  Routines
+   with "rel" or "full" in the name have release semantics.  Routines with
+   "no_barrier" in the name have neither acquire not release semantics.
+
+   The routines may be implemented as macros.
+
+   // Atomic operations act on an intergral_type gpr_atm that is guaranteed to
+   // be the same size as a pointer.
+   typedef intptr_t gpr_atm;
+
+   // A memory barrier, providing both acquire and release semantics, but not
+   // otherwise acting on memory.
+   void gpr_atm_full_barrier(void);
+
+   // Atomically return *p, with acquire semantics.
+   gpr_atm gpr_atm_acq_load(gpr_atm *p);
+
+   // Atomically set *p = value, with release semantics.
+   void gpr_atm_rel_store(gpr_atm *p, gpr_atm value);
+
+   // Atomically add delta to *p, and return the old value of *p, with
+   // the barriers specified.
+   gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p, gpr_atm delta);
+   gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta);
+
+   // Atomically, if *p==o, set *p=n and return non-zero otherwise return 0,
+   // with the barriers specified if the operation succeeds.
+   int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
+   int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
+   int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
+*/
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#if defined(GPR_GCC_ATOMIC)
+#include <grpc/impl/codegen/atm_gcc_atomic.h>
+#elif defined(GPR_GCC_SYNC)
+#include <grpc/impl/codegen/atm_gcc_sync.h>
+#elif defined(GPR_WIN32_ATOMIC)
+#include <grpc/impl/codegen/atm_win32.h>
+#else
+#error could not determine platform for atm
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_ATM_H */
diff --git a/include/grpc/impl/codegen/atm_gcc_atomic.h b/include/grpc/impl/codegen/atm_gcc_atomic.h
new file mode 100644
index 0000000..8caf7ed
--- /dev/null
+++ b/include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
+#define GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
+
+/* atm_platform.h for gcc and gcc-like compilers with the
+   __atomic_* interface.  */
+#include <grpc/impl/codegen/port_platform.h>
+
+typedef intptr_t gpr_atm;
+
+#define gpr_atm_full_barrier() (__atomic_thread_fence(__ATOMIC_SEQ_CST))
+
+#define gpr_atm_acq_load(p) (__atomic_load_n((p), __ATOMIC_ACQUIRE))
+#define gpr_atm_no_barrier_load(p) (__atomic_load_n((p), __ATOMIC_RELAXED))
+#define gpr_atm_rel_store(p, value) \
+  (__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELEASE))
+#define gpr_atm_no_barrier_store(p, value) \
+  (__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELAXED))
+
+#define gpr_atm_no_barrier_fetch_add(p, delta) \
+  (__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_RELAXED))
+#define gpr_atm_full_fetch_add(p, delta) \
+  (__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_ACQ_REL))
+
+static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+  return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELAXED,
+                                     __ATOMIC_RELAXED);
+}
+
+static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+  return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQUIRE,
+                                     __ATOMIC_RELAXED);
+}
+
+static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+  return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELEASE,
+                                     __ATOMIC_RELAXED);
+}
+
+#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */
diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h
new file mode 100644
index 0000000..915b09f
--- /dev/null
+++ b/include/grpc/impl/codegen/atm_gcc_sync.h
@@ -0,0 +1,87 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H
+#define GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H
+
+/* variant of atm_platform.h for gcc and gcc-like compiers with __sync_*
+   interface */
+#include <grpc/impl/codegen/port_platform.h>
+
+typedef intptr_t gpr_atm;
+
+#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
+
+#if defined(__i386) || defined(__x86_64__)
+/* All loads are acquire loads and all stores are release stores.  */
+#define GPR_ATM_LS_BARRIER_() GPR_ATM_COMPILE_BARRIER_()
+#else
+#define GPR_ATM_LS_BARRIER_() gpr_atm_full_barrier()
+#endif
+
+#define gpr_atm_full_barrier() (__sync_synchronize())
+
+static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
+  gpr_atm value = *p;
+  GPR_ATM_LS_BARRIER_();
+  return value;
+}
+
+static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
+  gpr_atm value = *p;
+  GPR_ATM_COMPILE_BARRIER_();
+  return value;
+}
+
+static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
+  GPR_ATM_LS_BARRIER_();
+  *p = value;
+}
+
+static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
+  GPR_ATM_COMPILE_BARRIER_();
+  *p = value;
+}
+
+#undef GPR_ATM_LS_BARRIER_
+#undef GPR_ATM_COMPILE_BARRIER_
+
+#define gpr_atm_no_barrier_fetch_add(p, delta) \
+  gpr_atm_full_fetch_add((p), (delta))
+#define gpr_atm_full_fetch_add(p, delta) (__sync_fetch_and_add((p), (delta)))
+
+#define gpr_atm_no_barrier_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
+#define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
+#define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
+
+#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H */
diff --git a/include/grpc/impl/codegen/atm_win32.h b/include/grpc/impl/codegen/atm_win32.h
new file mode 100644
index 0000000..7c1ccaf
--- /dev/null
+++ b/include/grpc/impl/codegen/atm_win32.h
@@ -0,0 +1,125 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_ATM_WIN32_H
+#define GRPC_IMPL_CODEGEN_ATM_WIN32_H
+
+/* Win32 variant of atm_platform.h */
+#include <grpc/impl/codegen/port_platform.h>
+
+typedef intptr_t gpr_atm;
+
+#define gpr_atm_full_barrier MemoryBarrier
+
+static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
+  gpr_atm result = *p;
+  gpr_atm_full_barrier();
+  return result;
+}
+
+static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
+  /* TODO(dklempner): Can we implement something better here? */
+  return gpr_atm_acq_load(p);
+}
+
+static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
+  gpr_atm_full_barrier();
+  *p = value;
+}
+
+static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
+  /* TODO(ctiller): Can we implement something better here? */
+  gpr_atm_rel_store(p, value);
+}
+
+static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+/* InterlockedCompareExchangePointerNoFence() not available on vista or
+   windows7 */
+#ifdef GPR_ARCH_64
+  return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
+                  (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
+#else
+  return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
+                                                         (LONG)n, (LONG)o);
+#endif
+}
+
+static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+#ifdef GPR_ARCH_64
+  return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
+                  (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
+#else
+  return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
+                                                         (LONG)n, (LONG)o);
+#endif
+}
+
+static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+#ifdef GPR_ARCH_64
+  return o == (gpr_atm)InterlockedCompareExchangeRelease64(
+                  (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
+#else
+  return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG *)p,
+                                                         (LONG)n, (LONG)o);
+#endif
+}
+
+static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p,
+                                                     gpr_atm delta) {
+  /* Use the CAS operation to get pointer-sized fetch and add */
+  gpr_atm old;
+  do {
+    old = *p;
+  } while (!gpr_atm_no_barrier_cas(p, old, old + delta));
+  return old;
+}
+
+static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta) {
+  /* Use a CAS operation to get pointer-sized fetch and add */
+  gpr_atm old;
+#ifdef GPR_ARCH_64
+  do {
+    old = *p;
+  } while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG *)p,
+                                                        (LONGLONG)old + delta,
+                                                        (LONGLONG)old));
+#else
+  do {
+    old = *p;
+  } while (old != (gpr_atm)InterlockedCompareExchange(
+                      (volatile LONG *)p, (LONG)old + delta, (LONG)old));
+#endif
+  return old;
+}
+
+#endif /* GRPC_IMPL_CODEGEN_ATM_WIN32_H */
diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h
new file mode 100644
index 0000000..35f3c6e
--- /dev/null
+++ b/include/grpc/impl/codegen/byte_buffer.h
@@ -0,0 +1,120 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
+#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
+
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/impl/codegen/slice_buffer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  GRPC_BB_RAW
+  /* Future types may include GRPC_BB_PROTOBUF, etc. */
+} grpc_byte_buffer_type;
+
+struct grpc_byte_buffer {
+  void *reserved;
+  grpc_byte_buffer_type type;
+  union {
+    struct {
+      void *reserved[8];
+    } reserved;
+    struct {
+      grpc_compression_algorithm compression;
+      gpr_slice_buffer slice_buffer;
+    } raw;
+  } data;
+};
+typedef struct grpc_byte_buffer grpc_byte_buffer;
+
+/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
+ *
+ * Increases the reference count for all \a slices processed. The user is
+ * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
+grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
+                                              size_t nslices);
+
+/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
+ * \a nslices). The \a compression argument defines the compression algorithm
+ * used to generate the data in \a slices.
+ *
+ * Increases the reference count for all \a slices processed. The user is
+ * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
+grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
+    gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
+
+/** Copies input byte buffer \a bb.
+ *
+ * Increases the reference count of all the source slices. The user is
+ * responsible for calling grpc_byte_buffer_destroy over the returned copy. */
+grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
+
+/** Returns the size of the given byte buffer, in bytes. */
+size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
+
+/** Destroys \a byte_buffer deallocating all its memory. */
+void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
+
+/** Reader for byte buffers. Iterates over slices in the byte buffer */
+struct grpc_byte_buffer_reader;
+typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
+
+/** Initialize \a reader to read over \a buffer */
+void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
+                                  grpc_byte_buffer *buffer);
+
+/** Cleanup and destroy \a reader */
+void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
+
+/** Updates \a slice with the next piece of data from from \a reader and returns
+ * 1. Returns 0 at the end of the stream. Caller is responsible for calling
+ * gpr_slice_unref on the result. */
+int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
+                                 gpr_slice *slice);
+
+/** Merge all data from \a reader into single slice */
+gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
+
+/** Returns a RAW byte buffer instance from the output of \a reader. */
+grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
+    grpc_byte_buffer_reader *reader);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_BYTE_BUFFER_H */
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
new file mode 100644
index 0000000..f552d3c
--- /dev/null
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
+#define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** To be used in channel arguments */
+#define GRPC_COMPRESSION_ALGORITHM_ARG "grpc.compression_algorithm"
+#define GRPC_COMPRESSION_ALGORITHM_STATE_ARG "grpc.compression_algorithm_state"
+
+/* The various compression algorithms supported by GRPC */
+typedef enum {
+  GRPC_COMPRESS_NONE = 0,
+  GRPC_COMPRESS_DEFLATE,
+  GRPC_COMPRESS_GZIP,
+  /* TODO(ctiller): snappy */
+  GRPC_COMPRESS_ALGORITHMS_COUNT
+} grpc_compression_algorithm;
+
+typedef enum {
+  GRPC_COMPRESS_LEVEL_NONE = 0,
+  GRPC_COMPRESS_LEVEL_LOW,
+  GRPC_COMPRESS_LEVEL_MED,
+  GRPC_COMPRESS_LEVEL_HIGH,
+  GRPC_COMPRESS_LEVEL_COUNT
+} grpc_compression_level;
+
+typedef struct grpc_compression_options {
+  uint32_t enabled_algorithms_bitset; /**< All algs are enabled by default */
+  grpc_compression_algorithm default_compression_algorithm; /**< for channel */
+} grpc_compression_options;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H */
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
new file mode 100644
index 0000000..ea1e96c
--- /dev/null
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -0,0 +1,373 @@
+/*
+ *
+ * Copyright 2015-2016, 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
+#define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
+
+#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/status.h>
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Completion Queues enable notification of the completion of asynchronous
+    actions. */
+typedef struct grpc_completion_queue grpc_completion_queue;
+
+/** An alarm associated with a completion queue. */
+typedef struct grpc_alarm grpc_alarm;
+
+/** The Channel interface allows creation of Call objects. */
+typedef struct grpc_channel grpc_channel;
+
+/** A server listens to some port and responds to request calls */
+typedef struct grpc_server grpc_server;
+
+/** A Call represents an RPC. When created, it is in a configuration state
+    allowing properties to be set until it is invoked. After invoke, the Call
+    can have messages written to it and read from it. */
+typedef struct grpc_call grpc_call;
+
+/** Type specifier for grpc_arg */
+typedef enum {
+  GRPC_ARG_STRING,
+  GRPC_ARG_INTEGER,
+  GRPC_ARG_POINTER
+} grpc_arg_type;
+
+/** A single argument... each argument has a key and a value
+
+    A note on naming keys:
+      Keys are namespaced into groups, usually grouped by library, and are
+      keys for module XYZ are named XYZ.key1, XYZ.key2, etc. Module names must
+      be restricted to the regex [A-Za-z][_A-Za-z0-9]{,15}.
+      Key names must be restricted to the regex [A-Za-z][_A-Za-z0-9]{,47}.
+
+    GRPC core library keys are prefixed by grpc.
+
+    Library authors are strongly encouraged to \#define symbolic constants for
+    their keys so that it's possible to change them in the future. */
+typedef struct {
+  grpc_arg_type type;
+  char *key;
+  union {
+    char *string;
+    int integer;
+    struct {
+      void *p;
+      void *(*copy)(void *p);
+      void (*destroy)(void *p);
+    } pointer;
+  } value;
+} grpc_arg;
+
+/** An array of arguments that can be passed around.
+
+    Used to set optional channel-level configuration.
+    These configuration options are modelled as key-value pairs as defined
+    by grpc_arg; keys are strings to allow easy backwards-compatible extension
+    by arbitrary parties.
+    All evaluation is performed at channel creation time (i.e. the values in
+    this structure need only live through the creation invocation). */
+typedef struct {
+  size_t num_args;
+  grpc_arg *args;
+} grpc_channel_args;
+
+/* Channel argument keys: */
+/** Enable census for tracing and stats collection */
+#define GRPC_ARG_ENABLE_CENSUS "grpc.census"
+/** Maximum number of concurrent incoming streams to allow on a http2
+    connection */
+#define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
+/** Maximum message length that the channel can receive */
+#define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length"
+/** Initial sequence number for http2 transports */
+#define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \
+  "grpc.http2.initial_sequence_number"
+/** Amount to read ahead on individual streams. Defaults to 64kb, larger
+    values can help throughput on high-latency connections.
+    NOTE: at some point we'd like to auto-tune this, and this parameter
+    will become a no-op. */
+#define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
+/** How much memory to use for hpack decoding */
+#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
+  "grpc.http2.hpack_table_size.decoder"
+/** How much memory to use for hpack encoding */
+#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
+  "grpc.http2.hpack_table_size.encoder"
+/** Default authority to pass if none specified on call construction */
+#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
+/** Primary user agent: goes at the start of the user-agent metadata
+    sent on each request */
+#define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent"
+/** Secondary user agent: goes at the end of the user-agent metadata
+    sent on each request */
+#define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent"
+/* The caller of the secure_channel_create functions may override the target
+   name used for SSL host name checking using this channel argument which is of
+   type GRPC_ARG_STRING. This *should* be used for testing only.
+   If this argument is not specified, the name used for SSL host name checking
+   will be the target parameter (assuming that the secure channel is an SSL
+   channel). If this parameter is specified and the underlying is not an SSL
+   channel, it will just be ignored. */
+#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
+
+/** Result of a grpc call. If the caller satisfies the prerequisites of a
+    particular operation, the grpc_call_error returned will be GRPC_CALL_OK.
+    Receiving any other value listed here is an indication of a bug in the
+    caller. */
+typedef enum grpc_call_error {
+  /** everything went ok */
+  GRPC_CALL_OK = 0,
+  /** something failed, we don't know what */
+  GRPC_CALL_ERROR,
+  /** this method is not available on the server */
+  GRPC_CALL_ERROR_NOT_ON_SERVER,
+  /** this method is not available on the client */
+  GRPC_CALL_ERROR_NOT_ON_CLIENT,
+  /** this method must be called before server_accept */
+  GRPC_CALL_ERROR_ALREADY_ACCEPTED,
+  /** this method must be called before invoke */
+  GRPC_CALL_ERROR_ALREADY_INVOKED,
+  /** this method must be called after invoke */
+  GRPC_CALL_ERROR_NOT_INVOKED,
+  /** this call is already finished
+      (writes_done or write_status has already been called) */
+  GRPC_CALL_ERROR_ALREADY_FINISHED,
+  /** there is already an outstanding read/write operation on the call */
+  GRPC_CALL_ERROR_TOO_MANY_OPERATIONS,
+  /** the flags value was illegal for this call */
+  GRPC_CALL_ERROR_INVALID_FLAGS,
+  /** invalid metadata was passed to this call */
+  GRPC_CALL_ERROR_INVALID_METADATA,
+  /** invalid message was passed to this call */
+  GRPC_CALL_ERROR_INVALID_MESSAGE,
+  /** completion queue for notification has not been registered with the
+      server */
+  GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE,
+  /** this batch of operations leads to more operations than allowed */
+  GRPC_CALL_ERROR_BATCH_TOO_BIG
+} grpc_call_error;
+
+/* Write Flags: */
+/** Hint that the write may be buffered and need not go out on the wire
+    immediately. GRPC is free to buffer the message until the next non-buffered
+    write, or until writes_done, but it need not buffer completely or at all. */
+#define GRPC_WRITE_BUFFER_HINT (0x00000001u)
+/** Force compression to be disabled for a particular write
+    (start_write/add_metadata). Illegal on invoke/accept. */
+#define GRPC_WRITE_NO_COMPRESS (0x00000002u)
+/** Mask of all valid flags. */
+#define GRPC_WRITE_USED_MASK (GRPC_WRITE_BUFFER_HINT | GRPC_WRITE_NO_COMPRESS)
+
+/** A single metadata element */
+typedef struct grpc_metadata {
+  const char *key;
+  const char *value;
+  size_t value_length;
+  uint32_t flags;
+
+  /** The following fields are reserved for grpc internal use.
+      There is no need to initialize them, and they will be set to garbage
+      during calls to grpc. */
+  struct {
+    void *obfuscated[4];
+  } internal_data;
+} grpc_metadata;
+
+/** The type of completion (for grpc_event) */
+typedef enum grpc_completion_type {
+  /** Shutting down */
+  GRPC_QUEUE_SHUTDOWN,
+  /** No event before timeout */
+  GRPC_QUEUE_TIMEOUT,
+  /** Operation completion */
+  GRPC_OP_COMPLETE
+} grpc_completion_type;
+
+/** The result of an operation.
+
+    Returned by a completion queue when the operation started with tag. */
+typedef struct grpc_event {
+  /** The type of the completion. */
+  grpc_completion_type type;
+  /** non-zero if the operation was successful, 0 upon failure.
+      Only GRPC_OP_COMPLETE can succeed or fail. */
+  int success;
+  /** The tag passed to grpc_call_start_batch etc to start this operation.
+      Only GRPC_OP_COMPLETE has a tag. */
+  void *tag;
+} grpc_event;
+
+typedef struct {
+  size_t count;
+  size_t capacity;
+  grpc_metadata *metadata;
+} grpc_metadata_array;
+
+typedef struct {
+  char *method;
+  size_t method_capacity;
+  char *host;
+  size_t host_capacity;
+  gpr_timespec deadline;
+  void *reserved;
+} grpc_call_details;
+
+typedef enum {
+  /** Send initial metadata: one and only one instance MUST be sent for each
+      call, unless the call was cancelled - in which case this can be skipped.
+      This op completes after all bytes of metadata have been accepted by
+      outgoing flow control. */
+  GRPC_OP_SEND_INITIAL_METADATA = 0,
+  /** Send a message: 0 or more of these operations can occur for each call.
+      This op completes after all bytes for the message have been accepted by
+      outgoing flow control. */
+  GRPC_OP_SEND_MESSAGE,
+  /** Send a close from the client: one and only one instance MUST be sent from
+      the client, unless the call was cancelled - in which case this can be
+      skipped.
+      This op completes after all bytes for the call (including the close)
+      have passed outgoing flow control. */
+  GRPC_OP_SEND_CLOSE_FROM_CLIENT,
+  /** Send status from the server: one and only one instance MUST be sent from
+      the server unless the call was cancelled - in which case this can be
+      skipped.
+      This op completes after all bytes for the call (including the status)
+      have passed outgoing flow control. */
+  GRPC_OP_SEND_STATUS_FROM_SERVER,
+  /** Receive initial metadata: one and only one MUST be made on the client,
+      must not be made on the server.
+      This op completes after all initial metadata has been read from the
+      peer. */
+  GRPC_OP_RECV_INITIAL_METADATA,
+  /** Receive a message: 0 or more of these operations can occur for each call.
+      This op completes after all bytes of the received message have been
+      read, or after a half-close has been received on this call. */
+  GRPC_OP_RECV_MESSAGE,
+  /** Receive status on the client: one and only one must be made on the client.
+      This operation always succeeds, meaning ops paired with this operation
+      will also appear to succeed, even though they may not have. In that case
+      the status will indicate some failure.
+      This op completes after all activity on the call has completed. */
+  GRPC_OP_RECV_STATUS_ON_CLIENT,
+  /** Receive close on the server: one and only one must be made on the
+      server.
+      This op completes after the close has been received by the server. */
+  GRPC_OP_RECV_CLOSE_ON_SERVER
+} grpc_op_type;
+
+/** Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT
+   which has no arguments) */
+typedef struct grpc_op {
+  /** Operation type, as defined by grpc_op_type */
+  grpc_op_type op;
+  /** Write flags bitset for grpc_begin_messages */
+  uint32_t flags;
+  /** Reserved for future usage */
+  void *reserved;
+  union {
+    /** Reserved for future usage */
+    struct {
+      void *reserved[8];
+    } reserved;
+    struct {
+      size_t count;
+      grpc_metadata *metadata;
+    } send_initial_metadata;
+    grpc_byte_buffer *send_message;
+    struct {
+      size_t trailing_metadata_count;
+      grpc_metadata *trailing_metadata;
+      grpc_status_code status;
+      const char *status_details;
+    } send_status_from_server;
+    /** ownership of the array is with the caller, but ownership of the elements
+        stays with the call object (ie key, value members are owned by the call
+        object, recv_initial_metadata->array is owned by the caller).
+        After the operation completes, call grpc_metadata_array_destroy on this
+        value, or reuse it in a future op. */
+    grpc_metadata_array *recv_initial_metadata;
+    /** ownership of the byte buffer is moved to the caller; the caller must
+        call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
+       */
+    grpc_byte_buffer **recv_message;
+    struct {
+      /** ownership of the array is with the caller, but ownership of the
+          elements stays with the call object (ie key, value members are owned
+          by the call object, trailing_metadata->array is owned by the caller).
+          After the operation completes, call grpc_metadata_array_destroy on
+         this
+          value, or reuse it in a future op. */
+      grpc_metadata_array *trailing_metadata;
+      grpc_status_code *status;
+      /** status_details is a buffer owned by the application before the op
+          completes and after the op has completed. During the operation
+          status_details may be reallocated to a size larger than
+          *status_details_capacity, in which case *status_details_capacity will
+          be updated with the new array capacity.
+
+          Pre-allocating space:
+          size_t my_capacity = 8;
+          char *my_details = gpr_malloc(my_capacity);
+          x.status_details = &my_details;
+          x.status_details_capacity = &my_capacity;
+
+          Not pre-allocating space:
+          size_t my_capacity = 0;
+          char *my_details = NULL;
+          x.status_details = &my_details;
+          x.status_details_capacity = &my_capacity;
+
+          After the call:
+          gpr_free(my_details); */
+      char **status_details;
+      size_t *status_details_capacity;
+    } recv_status_on_client;
+    struct {
+      /** out argument, set to 1 if the call failed in any way (seen as a
+          cancellation on the server), or 0 if the call succeeded */
+      int *cancelled;
+    } recv_close_on_server;
+  } data;
+} grpc_op;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_GRPC_TYPES_H */
diff --git a/include/grpc/impl/codegen/log.h b/include/grpc/impl/codegen/log.h
new file mode 100644
index 0000000..30f6a5d
--- /dev/null
+++ b/include/grpc/impl/codegen/log.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_LOG_H
+#define GRPC_IMPL_CODEGEN_LOG_H
+
+#include <stdlib.h> /* for abort() */
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GPR log API.
+
+   Usage (within grpc):
+
+   int argument1 = 3;
+   char* argument2 = "hello";
+   gpr_log(GPR_DEBUG, "format string %d", argument1);
+   gpr_log(GPR_INFO, "hello world");
+   gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
+
+/* The severity of a log message - use the #defines below when calling into
+   gpr_log to additionally supply file and line data */
+typedef enum gpr_log_severity {
+  GPR_LOG_SEVERITY_DEBUG,
+  GPR_LOG_SEVERITY_INFO,
+  GPR_LOG_SEVERITY_ERROR
+} gpr_log_severity;
+
+/* Returns a string representation of the log severity */
+const char *gpr_log_severity_string(gpr_log_severity severity);
+
+/* Macros to build log contexts at various severity levels */
+#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
+#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
+#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
+
+/* Log a message. It's advised to use GPR_xxx above to generate the context
+ * for each message */
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...);
+
+void gpr_log_message(const char *file, int line, gpr_log_severity severity,
+                     const char *message);
+
+/* Log overrides: applications can use this API to intercept logging calls
+   and use their own implementations */
+
+typedef struct {
+  const char *file;
+  int line;
+  gpr_log_severity severity;
+  const char *message;
+} gpr_log_func_args;
+
+typedef void (*gpr_log_func)(gpr_log_func_args *args);
+void gpr_set_log_function(gpr_log_func func);
+
+/* abort() the process if x is zero, having written a line to the log.
+
+   Intended for internal invariants.  If the error can be recovered from,
+   without the possibility of corruption, or might best be reflected via
+   an exception in a higher-level language, consider returning error code.  */
+#define GPR_ASSERT(x)                                 \
+  do {                                                \
+    if (!(x)) {                                       \
+      gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
+      abort();                                        \
+    }                                                 \
+  } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_LOG_H */
diff --git a/include/grpc/impl/codegen/propagation_bits.h b/include/grpc/impl/codegen/propagation_bits.h
new file mode 100644
index 0000000..9cb8788
--- /dev/null
+++ b/include/grpc/impl/codegen/propagation_bits.h
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_H
+#define GRPC_IMPL_CODEGEN_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Propagation bits: this can be bitwise or-ed to form propagation_mask for
+ * grpc_call */
+/** Propagate deadline */
+#define GRPC_PROPAGATE_DEADLINE ((uint32_t)1)
+/** Propagate census context */
+#define GRPC_PROPAGATE_CENSUS_STATS_CONTEXT ((uint32_t)2)
+#define GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT ((uint32_t)4)
+/** Propagate cancellation */
+#define GRPC_PROPAGATE_CANCELLATION ((uint32_t)8)
+
+/* Default propagation mask: clients of the core API are encouraged to encode
+   deltas from this in their implementations... ie write:
+   GRPC_PROPAGATE_DEFAULTS & ~GRPC_PROPAGATE_DEADLINE to disable deadline
+   propagation. Doing so gives flexibility in the future to define new
+   propagation types that are default inherited or not. */
+#define GRPC_PROPAGATE_DEFAULTS                                                \
+  ((uint32_t)((                                                                \
+      0xffff | GRPC_PROPAGATE_DEADLINE | GRPC_PROPAGATE_CENSUS_STATS_CONTEXT | \
+      GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT | GRPC_PROPAGATE_CANCELLATION)))
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* GRPC_IMPL_CODEGEN_H */
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
new file mode 100644
index 0000000..296ef99
--- /dev/null
+++ b/include/grpc/impl/codegen/slice.h
@@ -0,0 +1,182 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_SLICE_H
+#define GRPC_IMPL_CODEGEN_SLICE_H
+
+#include <grpc/impl/codegen/sync.h>
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Slice API
+
+   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.
+
+   The data-structure for slices is exposed here to allow non-gpr code to
+   build slices from whatever data they have available.
+
+   When defining interfaces that handle slices, care should be taken to define
+   reference ownership semantics (who should call unref?) and mutability
+   constraints (is the callee allowed to modify the slice?) */
+
+/* Reference count container for gpr_slice. Contains function pointers to
+   increment and decrement reference counts. Implementations should cleanup
+   when the reference count drops to zero.
+   Typically client code should not touch this, and use gpr_slice_malloc,
+   gpr_slice_new, or gpr_slice_new_with_len instead. */
+typedef struct gpr_slice_refcount {
+  void (*ref)(void *);
+  void (*unref)(void *);
+} gpr_slice_refcount;
+
+#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
+
+/* A gpr_slice s, if initialized, represents the byte range
+   s.bytes[0..s.length-1].
+
+   It can have an associated ref count which has a destruction routine to be run
+   when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()).
+   Multiple gpr_slice values may share a ref count.
+
+   If the slice does not have a refcount, it represents an inlined small piece
+   of data that is copied by value. */
+typedef struct gpr_slice {
+  struct gpr_slice_refcount *refcount;
+  union {
+    struct {
+      uint8_t *bytes;
+      size_t length;
+    } refcounted;
+    struct {
+      uint8_t length;
+      uint8_t bytes[GPR_SLICE_INLINED_SIZE];
+    } inlined;
+  } data;
+} gpr_slice;
+
+#define GPR_SLICE_START_PTR(slice)                  \
+  ((slice).refcount ? (slice).data.refcounted.bytes \
+                    : (slice).data.inlined.bytes)
+#define GPR_SLICE_LENGTH(slice)                      \
+  ((slice).refcount ? (slice).data.refcounted.length \
+                    : (slice).data.inlined.length)
+#define GPR_SLICE_SET_LENGTH(slice, newlen)                               \
+  ((slice).refcount ? ((slice).data.refcounted.length = (size_t)(newlen)) \
+                    : ((slice).data.inlined.length = (uint8_t)(newlen)))
+#define GPR_SLICE_END_PTR(slice) \
+  GPR_SLICE_START_PTR(slice) + GPR_SLICE_LENGTH(slice)
+#define GPR_SLICE_IS_EMPTY(slice) (GPR_SLICE_LENGTH(slice) == 0)
+
+/* Increment the refcount of s. Requires slice is initialized.
+   Returns s. */
+gpr_slice gpr_slice_ref(gpr_slice s);
+
+/* Decrement the ref count of s.  If the ref count of s reaches zero, all
+   slices sharing the ref count are destroyed, and considered no longer
+   initialized.  If s is ultimately derived from a call to gpr_slice_new(start,
+   len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is
+   ultimately derived from a call to gpr_slice_new_with_len(start, len, dest)
+   where dest!=NULL , then (*dest)(start, len).  Requires s initialized.  */
+void gpr_slice_unref(gpr_slice s);
+
+/* Create a slice pointing at some data. Calls malloc to allocate a refcount
+   for the object, and arranges that destroy will be called with the pointer
+   passed in at destruction. */
+gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
+
+/* Equivalent to gpr_slice_new, but with a two argument destroy function that
+   also takes the slice length. */
+gpr_slice gpr_slice_new_with_len(void *p, size_t len,
+                                 void (*destroy)(void *, size_t));
+
+/* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
+   call.
+   Aborts if malloc() fails. */
+gpr_slice gpr_slice_malloc(size_t length);
+
+/* Create a slice by copying a string.
+   Does not preserve null terminators.
+   Equivalent to:
+     size_t len = strlen(source);
+     gpr_slice slice = gpr_slice_malloc(len);
+     memcpy(slice->data, source, len); */
+gpr_slice gpr_slice_from_copied_string(const char *source);
+
+/* Create a slice by copying a buffer.
+   Equivalent to:
+     gpr_slice slice = gpr_slice_malloc(len);
+     memcpy(slice->data, source, len); */
+gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
+
+/* Create a slice pointing to constant memory */
+gpr_slice gpr_slice_from_static_string(const char *source);
+
+/* Return a result slice derived from s, which shares a ref count with s, where
+   result.data==s.data+begin, and result.length==end-begin.
+   The ref count of s is increased by one.
+   Requires s initialized, begin <= end, begin <= s.length, and
+   end <= source->length. */
+gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
+
+/* The same as gpr_slice_sub, but without altering the ref count */
+gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
+
+/* Splits s into two: modifies s to be s[0:split], and returns a new slice,
+   sharing a refcount with s, that contains s[split:s.length].
+   Requires s intialized, split <= s.length */
+gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
+
+/* Splits s into two: modifies s to be s[split:s.length], and returns a new
+   slice, sharing a refcount with s, that contains s[0:split].
+   Requires s intialized, split <= s.length */
+gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
+
+gpr_slice gpr_empty_slice(void);
+
+/* Returns <0 if a < b, ==0 if a == b, >0 if a > b
+   The order is arbitrary, and is not guaranteed to be stable across different
+   versions of the API. */
+int gpr_slice_cmp(gpr_slice a, gpr_slice b);
+int gpr_slice_str_cmp(gpr_slice a, const char *b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_SLICE_H */
diff --git a/include/grpc/impl/codegen/slice_buffer.h b/include/grpc/impl/codegen/slice_buffer.h
new file mode 100644
index 0000000..b8d6a11
--- /dev/null
+++ b/include/grpc/impl/codegen/slice_buffer.h
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_SLICE_BUFFER_H
+#define GRPC_IMPL_CODEGEN_SLICE_BUFFER_H
+
+#include <grpc/impl/codegen/slice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
+
+/* Represents an expandable array of slices, to be interpreted as a single item
+   TODO(ctiller): inline some small number of elements into the struct, to
+                  avoid per-call allocations */
+typedef struct {
+  /* slices in the array */
+  gpr_slice *slices;
+  /* the number of slices in the array */
+  size_t count;
+  /* the number of slices allocated in the array */
+  size_t capacity;
+  /* the combined length of all slices in the array */
+  size_t length;
+  /* inlined elements to avoid allocations */
+  gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS];
+} gpr_slice_buffer;
+
+/* initialize a slice buffer */
+void gpr_slice_buffer_init(gpr_slice_buffer *sb);
+/* destroy a slice buffer - unrefs any held elements */
+void gpr_slice_buffer_destroy(gpr_slice_buffer *sb);
+/* Add an element to a slice buffer - takes ownership of the slice.
+   This function is allowed to concatenate the passed in slice to the end of
+   some other slice if desired by the slice buffer. */
+void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice);
+/* add an element to a slice buffer - takes ownership of the slice and returns
+   the index of the slice.
+   Guarantees that the slice will not be concatenated at the end of another
+   slice (i.e. the data for this slice will begin at the first byte of the
+   slice at the returned index in sb->slices)
+   The implementation MAY decide to concatenate data at the end of a small
+   slice added in this fashion. */
+size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice slice);
+void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices, size_t n);
+/* add a very small (less than 8 bytes) amount of data to the end of a slice
+   buffer: returns a pointer into which to add the data */
+uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len);
+/* pop the last buffer, but don't unref it */
+void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
+/* clear a slice buffer, unref all elements */
+void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb);
+/* swap the contents of two slice buffers */
+void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b);
+/* move all of the elements of src into dst */
+void gpr_slice_buffer_move_into(gpr_slice_buffer *src, gpr_slice_buffer *dst);
+/* remove n bytes from the end of a slice buffer */
+void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n,
+                               gpr_slice_buffer *garbage);
+/* move the first n bytes of src into dst */
+void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n,
+                                 gpr_slice_buffer *dst);
+/* take the first slice in the slice buffer */
+gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_SLICE_BUFFER_H */
diff --git a/include/grpc/impl/codegen/status.h b/include/grpc/impl/codegen/status.h
new file mode 100644
index 0000000..29e4570
--- /dev/null
+++ b/include/grpc/impl/codegen/status.h
@@ -0,0 +1,163 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_STATUS_H
+#define GRPC_IMPL_CODEGEN_STATUS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  /* Not an error; returned on success */
+  GRPC_STATUS_OK = 0,
+
+  /* The operation was cancelled (typically by the caller). */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_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). */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_DEADLINE_EXCEEDED = 4,
+
+  /* Some requested entity (e.g., file or directory) was not found. */
+  GRPC_STATUS_NOT_FOUND = 5,
+
+  /* Some entity that we attempted to create (e.g., file or directory)
+     already exists. */
+  GRPC_STATUS_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). */
+  GRPC_STATUS_PERMISSION_DENIED = 7,
+
+  /* The request does not have valid authentication credentials for the
+     operation. */
+  GRPC_STATUS_UNAUTHENTICATED = 16,
+
+  /* Some resource has been exhausted, perhaps a per-user quota, or
+     perhaps the entire file system is out of space. */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_OUT_OF_RANGE = 11,
+
+  /* Operation is not implemented or not supported/enabled in this service. */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_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. */
+  GRPC_STATUS_UNAVAILABLE = 14,
+
+  /* Unrecoverable data loss or corruption. */
+  GRPC_STATUS_DATA_LOSS = 15,
+
+  /* Force users to include a default branch: */
+  GRPC_STATUS__DO_NOT_USE = -1
+} grpc_status_code;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_STATUS_H */
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
new file mode 100644
index 0000000..052e39d
--- /dev/null
+++ b/include/grpc/impl/codegen/sync.h
@@ -0,0 +1,315 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_SYNC_H
+#define GRPC_IMPL_CODEGEN_SYNC_H
+/* Synchronization primitives for GPR.
+
+   The type  gpr_mu              provides a non-reentrant mutex (lock).
+
+   The type  gpr_cv              provides a condition variable.
+
+   The type  gpr_once            provides for one-time initialization.
+
+   The type gpr_event            provides one-time-setting, reading, and
+                                 waiting of a void*, with memory barriers.
+
+   The type gpr_refcount         provides an object reference counter,
+                                 with memory barriers suitable to control
+                                 object lifetimes.
+
+   The type gpr_stats_counter    provides an atomic statistics counter. It
+                                 provides no memory barriers.
+ */
+
+/* Platform-specific type declarations of gpr_mu and gpr_cv.   */
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpc/impl/codegen/sync_generic.h>
+
+#if defined(GPR_POSIX_SYNC)
+#include <grpc/impl/codegen/sync_posix.h>
+#elif defined(GPR_WIN32)
+#include <grpc/impl/codegen/sync_win32.h>
+#elif !defined(GPR_CUSTOM_SYNC)
+#error Unable to determine platform for sync
+#endif
+
+#include <grpc/impl/codegen/time.h> /* for gpr_timespec */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --- Mutex interface ---
+
+   At most one thread may hold an exclusive lock on a mutex at any given time.
+   Actions taken by a thread that holds a mutex exclusively happen after
+   actions taken by all previous holders of the mutex.  Variables of type
+   gpr_mu are uninitialized when first declared.  */
+
+/* Initialize *mu.  Requires:  *mu uninitialized.  */
+void gpr_mu_init(gpr_mu *mu);
+
+/* Cause *mu no longer to be initialized, freeing any memory in use.  Requires:
+   *mu initialized; no other concurrent operation on *mu.  */
+void gpr_mu_destroy(gpr_mu *mu);
+
+/* Wait until no thread has a lock on *mu, cause the calling thread to own an
+   exclusive lock on *mu, then return.  May block indefinitely or crash if the
+   calling thread has a lock on *mu.  Requires:  *mu initialized.  */
+void gpr_mu_lock(gpr_mu *mu);
+
+/* Release an exclusive lock on *mu held by the calling thread.  Requires:  *mu
+   initialized; the calling thread holds an exclusive lock on *mu.  */
+void gpr_mu_unlock(gpr_mu *mu);
+
+/* Without blocking, attempt to acquire an exclusive lock on *mu for the
+   calling thread, then return non-zero iff success.  Fail, if any thread holds
+   the lock; succeeds with high probability if no thread holds the lock.
+   Requires:  *mu initialized.  */
+int gpr_mu_trylock(gpr_mu *mu);
+
+/* --- Condition variable interface ---
+
+   A while-loop should be used with gpr_cv_wait() when waiting for conditions
+   to become true.  See the example below.  Variables of type gpr_cv are
+   uninitialized when first declared.  */
+
+/* Initialize *cv.  Requires:  *cv uninitialized.  */
+void gpr_cv_init(gpr_cv *cv);
+
+/* Cause *cv no longer to be initialized, freeing any memory in use.  Requires:
+   *cv initialized; no other concurrent operation on *cv.*/
+void gpr_cv_destroy(gpr_cv *cv);
+
+/* Atomically release *mu and wait on *cv.  When the calling thread is woken
+   from *cv or the deadline abs_deadline is exceeded, execute gpr_mu_lock(mu)
+   and return whether the deadline was exceeded.  Use
+   abs_deadline==gpr_inf_future for no deadline.  May return even when not
+   woken explicitly.  Requires:  *mu and *cv initialized; the calling thread
+   holds an exclusive lock on *mu.  */
+int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
+
+/* If any threads are waiting on *cv, wake at least one.
+   Clients may treat this as an optimization of gpr_cv_broadcast()
+   for use in the case where waking more than one waiter is not useful.
+   Requires:  *cv initialized.  */
+void gpr_cv_signal(gpr_cv *cv);
+
+/* Wake all threads waiting on *cv.  Requires:  *cv initialized.  */
+void gpr_cv_broadcast(gpr_cv *cv);
+
+/* --- One-time initialization ---
+
+   gpr_once must be declared with static storage class, and initialized with
+   GPR_ONCE_INIT.  e.g.,
+     static gpr_once once_var = GPR_ONCE_INIT;     */
+
+/* Ensure that (*init_routine)() has been called exactly once (for the
+   specified gpr_once instance) and then return.
+   If multiple threads call gpr_once() on the same gpr_once instance, one of
+   them will call (*init_routine)(), and the others will block until that call
+   finishes.*/
+void gpr_once_init(gpr_once *once, void (*init_routine)(void));
+
+/* --- One-time event notification ---
+
+  These operations act on a gpr_event, which should be initialized with
+  gpr_ev_init(), or with GPR_EVENT_INIT if static, e.g.,
+       static gpr_event event_var = GPR_EVENT_INIT;
+  It requires no destruction.  */
+
+/* Initialize *ev. */
+void gpr_event_init(gpr_event *ev);
+
+/* Set *ev so that gpr_event_get() and gpr_event_wait() will return value.
+   Requires:  *ev initialized; value != NULL; no prior or concurrent calls to
+   gpr_event_set(ev, ...) since initialization.  */
+void gpr_event_set(gpr_event *ev, void *value);
+
+/* Return the value set by gpr_event_set(ev, ...), or NULL if no such call has
+   completed.  If the result is non-NULL, all operations that occurred prior to
+   the gpr_event_set(ev, ...) set will be visible after this call returns.
+   Requires:  *ev initialized.  This operation is faster than acquiring a mutex
+   on most platforms.  */
+void *gpr_event_get(gpr_event *ev);
+
+/* Wait until *ev is set by gpr_event_set(ev, ...), or abs_deadline is
+   exceeded, then return gpr_event_get(ev).  Requires:  *ev initialized.  Use
+   abs_deadline==gpr_inf_future for no deadline.  When the event has been
+   signalled before the call, this operation is faster than acquiring a mutex
+   on most platforms.  */
+void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
+
+/* --- Reference counting ---
+
+   These calls act on the type gpr_refcount.  It requires no destruction.  */
+
+/* Initialize *r to value n.  */
+void gpr_ref_init(gpr_refcount *r, int n);
+
+/* Increment the reference count *r.  Requires *r initialized. */
+void gpr_ref(gpr_refcount *r);
+
+/* Increment the reference count *r by n.  Requires *r initialized, n > 0. */
+void gpr_refn(gpr_refcount *r, int n);
+
+/* Decrement the reference count *r and return non-zero iff it has reached
+   zero. .  Requires *r initialized. */
+int gpr_unref(gpr_refcount *r);
+
+/* --- Stats counters ---
+
+   These calls act on the integral type gpr_stats_counter.  It requires no
+   destruction.  Static instances may be initialized with
+       gpr_stats_counter c = GPR_STATS_INIT;
+   Beware:  These operations do not imply memory barriers.  Do not use them to
+   synchronize other events.  */
+
+/* Initialize *c to the value n. */
+void gpr_stats_init(gpr_stats_counter *c, intptr_t n);
+
+/* *c += inc.  Requires: *c initialized. */
+void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc);
+
+/* Return *c.  Requires: *c initialized. */
+intptr_t gpr_stats_read(const gpr_stats_counter *c);
+
+/* ==================Example use of interface===================
+   A producer-consumer queue of up to N integers,
+   illustrating the use of the calls in this interface. */
+#if 0
+
+#define N 4
+
+   typedef struct queue {
+     gpr_cv non_empty;  /* Signalled when length becomes non-zero. */
+     gpr_cv non_full;   /* Signalled when length becomes non-N. */
+     gpr_mu mu;         /* Protects all fields below.
+                            (That is, except during initialization or
+                            destruction, the fields below should be accessed
+                            only by a thread that holds mu.) */
+     int head;           /* Index of head of queue 0..N-1. */
+     int length;         /* Number of valid elements in queue 0..N. */
+     int elem[N];        /* elem[head .. head+length-1] are queue elements. */
+   } queue;
+
+   /* Initialize *q. */
+   void queue_init(queue *q) {
+     gpr_mu_init(&q->mu);
+     gpr_cv_init(&q->non_empty);
+     gpr_cv_init(&q->non_full);
+     q->head = 0;
+     q->length = 0;
+   }
+
+   /* Free storage associated with *q. */
+   void queue_destroy(queue *q) {
+     gpr_mu_destroy(&q->mu);
+     gpr_cv_destroy(&q->non_empty);
+     gpr_cv_destroy(&q->non_full);
+   }
+
+   /* Wait until there is room in *q, then append x to *q. */
+   void queue_append(queue *q, int x) {
+     gpr_mu_lock(&q->mu);
+     /* To wait for a predicate without a deadline, loop on the negation of the
+        predicate, and use gpr_cv_wait(..., gpr_inf_future) inside the loop
+        to release the lock, wait, and reacquire on each iteration.  Code that
+        makes the condition true should use gpr_cv_broadcast() on the
+        corresponding condition variable.  The predicate must be on state
+        protected by the lock.  */
+     while (q->length == N) {
+       gpr_cv_wait(&q->non_full, &q->mu, gpr_inf_future);
+     }
+     if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
+       /* It's normal to use gpr_cv_broadcast() or gpr_signal() while
+          holding the lock. */
+       gpr_cv_broadcast(&q->non_empty);
+     }
+     q->elem[(q->head + q->length) % N] = x;
+     q->length++;
+     gpr_mu_unlock(&q->mu);
+   }
+
+   /* If it can be done without blocking, append x to *q and return non-zero.
+      Otherwise return 0. */
+   int queue_try_append(queue *q, int x) {
+     int result = 0;
+     if (gpr_mu_trylock(&q->mu)) {
+       if (q->length != N) {
+         if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
+           gpr_cv_broadcast(&q->non_empty);
+         }
+         q->elem[(q->head + q->length) % N] = x;
+         q->length++;
+         result = 1;
+       }
+       gpr_mu_unlock(&q->mu);
+     }
+     return result;
+   }
+
+   /* Wait until the *q is non-empty or deadline abs_deadline passes.  If the
+      queue is non-empty, remove its head entry, place it in *head, and return
+      non-zero.  Otherwise return 0.  */
+   int queue_remove(queue *q, int *head, gpr_timespec abs_deadline) {
+     int result = 0;
+     gpr_mu_lock(&q->mu);
+     /* To wait for a predicate with a deadline, loop on the negation of the
+        predicate or until gpr_cv_wait() returns true.  Code that makes
+        the condition true should use gpr_cv_broadcast() on the corresponding
+        condition variable.  The predicate must be on state protected by the
+        lock. */
+     while (q->length == 0 &&
+            !gpr_cv_wait(&q->non_empty, &q->mu, abs_deadline)) {
+     }
+     if (q->length != 0) {    /* Queue is non-empty. */
+       result = 1;
+       if (q->length == N) {  /* Wake threads blocked in queue_append(). */
+         gpr_cv_broadcast(&q->non_full);
+       }
+       *head = q->elem[q->head];
+       q->head = (q->head + 1) % N;
+       q->length--;
+     } /* else deadline exceeded */
+     gpr_mu_unlock(&q->mu);
+     return result;
+   }
+#endif /* 0 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_SYNC_H */
diff --git a/include/grpc/impl/codegen/sync_generic.h b/include/grpc/impl/codegen/sync_generic.h
new file mode 100644
index 0000000..75e85ae
--- /dev/null
+++ b/include/grpc/impl/codegen/sync_generic.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_SYNC_GENERIC_H
+#define GRPC_IMPL_CODEGEN_SYNC_GENERIC_H
+/* Generic type defintions for gpr_sync. */
+
+#include <grpc/impl/codegen/atm.h>
+
+/* gpr_event */
+typedef struct { gpr_atm state; } gpr_event;
+
+#define GPR_EVENT_INIT \
+  { 0 }
+
+/* gpr_refcount */
+typedef struct { gpr_atm count; } gpr_refcount;
+
+/* gpr_stats_counter */
+typedef struct { gpr_atm value; } gpr_stats_counter;
+
+#define GPR_STATS_INIT \
+  { 0 }
+
+#endif /* GRPC_IMPL_CODEGEN_SYNC_GENERIC_H */
diff --git a/include/grpc/impl/codegen/sync_posix.h b/include/grpc/impl/codegen/sync_posix.h
new file mode 100644
index 0000000..3d08cc3
--- /dev/null
+++ b/include/grpc/impl/codegen/sync_posix.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_SYNC_POSIX_H
+#define GRPC_IMPL_CODEGEN_SYNC_POSIX_H
+
+#include <grpc/impl/codegen/sync_generic.h>
+
+#include <pthread.h>
+
+typedef pthread_mutex_t gpr_mu;
+typedef pthread_cond_t gpr_cv;
+typedef pthread_once_t gpr_once;
+
+#define GPR_ONCE_INIT PTHREAD_ONCE_INIT
+
+#endif /* GRPC_IMPL_CODEGEN_SYNC_POSIX_H */
diff --git a/include/grpc/impl/codegen/sync_win32.h b/include/grpc/impl/codegen/sync_win32.h
new file mode 100644
index 0000000..bdc43dd
--- /dev/null
+++ b/include/grpc/impl/codegen/sync_win32.h
@@ -0,0 +1,49 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_SYNC_WIN32_H
+#define GRPC_IMPL_CODEGEN_SYNC_WIN32_H
+
+#include <grpc/impl/codegen/sync_generic.h>
+
+typedef struct {
+  CRITICAL_SECTION cs; /* Not an SRWLock until Vista is unsupported */
+  int locked;
+} gpr_mu;
+
+typedef CONDITION_VARIABLE gpr_cv;
+
+typedef INIT_ONCE gpr_once;
+#define GPR_ONCE_INIT INIT_ONCE_STATIC_INIT
+
+#endif /* GRPC_IMPL_CODEGEN_SYNC_WIN32_H */
diff --git a/include/grpc/status.h b/include/grpc/status.h
index 65ce410..67719b5 100644
--- a/include/grpc/status.h
+++ b/include/grpc/status.h
@@ -34,130 +34,6 @@
 #ifndef GRPC_STATUS_H
 #define GRPC_STATUS_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-  /* Not an error; returned on success */
-  GRPC_STATUS_OK = 0,
-
-  /* The operation was cancelled (typically by the caller). */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_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). */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_DEADLINE_EXCEEDED = 4,
-
-  /* Some requested entity (e.g., file or directory) was not found. */
-  GRPC_STATUS_NOT_FOUND = 5,
-
-  /* Some entity that we attempted to create (e.g., file or directory)
-     already exists. */
-  GRPC_STATUS_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). */
-  GRPC_STATUS_PERMISSION_DENIED = 7,
-
-  /* The request does not have valid authentication credentials for the
-     operation. */
-  GRPC_STATUS_UNAUTHENTICATED = 16,
-
-  /* Some resource has been exhausted, perhaps a per-user quota, or
-     perhaps the entire file system is out of space. */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_OUT_OF_RANGE = 11,
-
-  /* Operation is not implemented or not supported/enabled in this service. */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_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. */
-  GRPC_STATUS_UNAVAILABLE = 14,
-
-  /* Unrecoverable data loss or corruption. */
-  GRPC_STATUS_DATA_LOSS = 15,
-
-  /* Force users to include a default branch: */
-  GRPC_STATUS__DO_NOT_USE = -1
-} grpc_status_code;
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/status.h>
 
 #endif /* GRPC_STATUS_H */
diff --git a/include/grpc/support/atm.h b/include/grpc/support/atm.h
index cbb3813..a52e2fb 100644
--- a/include/grpc/support/atm.h
+++ b/include/grpc/support/atm.h
@@ -34,59 +34,6 @@
 #ifndef GRPC_SUPPORT_ATM_H
 #define GRPC_SUPPORT_ATM_H
 
-/* This interface provides atomic operations and barriers.
-   It is internal to gpr support code and should not be used outside it.
-
-   If an operation with acquire semantics precedes another memory access by the
-   same thread, the operation will precede that other access as seen by other
-   threads.
-
-   If an operation with release semantics follows another memory access by the
-   same thread, the operation will follow that other access as seen by other
-   threads.
-
-   Routines with "acq" or "full" in the name have acquire semantics.  Routines
-   with "rel" or "full" in the name have release semantics.  Routines with
-   "no_barrier" in the name have neither acquire not release semantics.
-
-   The routines may be implemented as macros.
-
-   // Atomic operations act on an intergral_type gpr_atm that is guaranteed to
-   // be the same size as a pointer.
-   typedef intptr_t gpr_atm;
-
-   // A memory barrier, providing both acquire and release semantics, but not
-   // otherwise acting on memory.
-   void gpr_atm_full_barrier(void);
-
-   // Atomically return *p, with acquire semantics.
-   gpr_atm gpr_atm_acq_load(gpr_atm *p);
-
-   // Atomically set *p = value, with release semantics.
-   void gpr_atm_rel_store(gpr_atm *p, gpr_atm value);
-
-   // Atomically add delta to *p, and return the old value of *p, with
-   // the barriers specified.
-   gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p, gpr_atm delta);
-   gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta);
-
-   // Atomically, if *p==o, set *p=n and return non-zero otherwise return 0,
-   // with the barriers specified if the operation succeeds.
-   int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
-   int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
-   int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
-*/
-
-#include <grpc/support/port_platform.h>
-
-#if defined(GPR_GCC_ATOMIC)
-#include <grpc/support/atm_gcc_atomic.h>
-#elif defined(GPR_GCC_SYNC)
-#include <grpc/support/atm_gcc_sync.h>
-#elif defined(GPR_WIN32_ATOMIC)
-#include <grpc/support/atm_win32.h>
-#else
-#error could not determine platform for atm
-#endif
+#include <grpc/impl/codegen/atm.h>
 
 #endif /* GRPC_SUPPORT_ATM_H */
diff --git a/include/grpc/support/atm_gcc_atomic.h b/include/grpc/support/atm_gcc_atomic.h
index 90d91dd..0aea543 100644
--- a/include/grpc/support/atm_gcc_atomic.h
+++ b/include/grpc/support/atm_gcc_atomic.h
@@ -31,42 +31,9 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_ATM_GCC_ATOMIC_H
-#define GRPC_SUPPORT_ATM_GCC_ATOMIC_H
+#ifndef GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
+#define GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
 
-/* atm_platform.h for gcc and gcc-like compilers with the
-   __atomic_* interface.  */
-#include <grpc/support/port_platform.h>
+#include <grpc/impl/codegen/atm_gcc_atomic.h>
 
-typedef intptr_t gpr_atm;
-
-#define gpr_atm_full_barrier() (__atomic_thread_fence(__ATOMIC_SEQ_CST))
-
-#define gpr_atm_acq_load(p) (__atomic_load_n((p), __ATOMIC_ACQUIRE))
-#define gpr_atm_no_barrier_load(p) (__atomic_load_n((p), __ATOMIC_RELAXED))
-#define gpr_atm_rel_store(p, value) \
-  (__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELEASE))
-#define gpr_atm_no_barrier_store(p, value) \
-  (__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELAXED))
-
-#define gpr_atm_no_barrier_fetch_add(p, delta) \
-  (__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_RELAXED))
-#define gpr_atm_full_fetch_add(p, delta) \
-  (__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_ACQ_REL))
-
-static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
-  return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELAXED,
-                                     __ATOMIC_RELAXED);
-}
-
-static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
-  return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQUIRE,
-                                     __ATOMIC_RELAXED);
-}
-
-static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
-  return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELEASE,
-                                     __ATOMIC_RELAXED);
-}
-
-#endif /* GRPC_SUPPORT_ATM_GCC_ATOMIC_H */
+#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */
diff --git a/include/grpc/support/atm_gcc_sync.h b/include/grpc/support/atm_gcc_sync.h
index 9d72cd4..b996d4a 100644
--- a/include/grpc/support/atm_gcc_sync.h
+++ b/include/grpc/support/atm_gcc_sync.h
@@ -34,54 +34,6 @@
 #ifndef GRPC_SUPPORT_ATM_GCC_SYNC_H
 #define GRPC_SUPPORT_ATM_GCC_SYNC_H
 
-/* variant of atm_platform.h for gcc and gcc-like compiers with __sync_*
-   interface */
-#include <grpc/support/port_platform.h>
-
-typedef intptr_t gpr_atm;
-
-#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
-
-#if defined(__i386) || defined(__x86_64__)
-/* All loads are acquire loads and all stores are release stores.  */
-#define GPR_ATM_LS_BARRIER_() GPR_ATM_COMPILE_BARRIER_()
-#else
-#define GPR_ATM_LS_BARRIER_() gpr_atm_full_barrier()
-#endif
-
-#define gpr_atm_full_barrier() (__sync_synchronize())
-
-static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
-  gpr_atm value = *p;
-  GPR_ATM_LS_BARRIER_();
-  return value;
-}
-
-static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
-  gpr_atm value = *p;
-  GPR_ATM_COMPILE_BARRIER_();
-  return value;
-}
-
-static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
-  GPR_ATM_LS_BARRIER_();
-  *p = value;
-}
-
-static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
-  GPR_ATM_COMPILE_BARRIER_();
-  *p = value;
-}
-
-#undef GPR_ATM_LS_BARRIER_
-#undef GPR_ATM_COMPILE_BARRIER_
-
-#define gpr_atm_no_barrier_fetch_add(p, delta) \
-  gpr_atm_full_fetch_add((p), (delta))
-#define gpr_atm_full_fetch_add(p, delta) (__sync_fetch_and_add((p), (delta)))
-
-#define gpr_atm_no_barrier_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
-#define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
-#define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
+#include <grpc/impl/codegen/atm_gcc_sync.h>
 
 #endif /* GRPC_SUPPORT_ATM_GCC_SYNC_H */
diff --git a/include/grpc/support/atm_win32.h b/include/grpc/support/atm_win32.h
index 8b1de76..13526d9 100644
--- a/include/grpc/support/atm_win32.h
+++ b/include/grpc/support/atm_win32.h
@@ -34,92 +34,6 @@
 #ifndef GRPC_SUPPORT_ATM_WIN32_H
 #define GRPC_SUPPORT_ATM_WIN32_H
 
-/* Win32 variant of atm_platform.h */
-#include <grpc/support/port_platform.h>
-
-typedef intptr_t gpr_atm;
-
-#define gpr_atm_full_barrier MemoryBarrier
-
-static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
-  gpr_atm result = *p;
-  gpr_atm_full_barrier();
-  return result;
-}
-
-static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
-  /* TODO(dklempner): Can we implement something better here? */
-  return gpr_atm_acq_load(p);
-}
-
-static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
-  gpr_atm_full_barrier();
-  *p = value;
-}
-
-static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
-  /* TODO(ctiller): Can we implement something better here? */
-  gpr_atm_rel_store(p, value);
-}
-
-static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
-/* InterlockedCompareExchangePointerNoFence() not available on vista or
-   windows7 */
-#ifdef GPR_ARCH_64
-  return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
-                  (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
-#else
-  return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
-                                                         (LONG)n, (LONG)o);
-#endif
-}
-
-static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
-#ifdef GPR_ARCH_64
-  return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
-                  (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
-#else
-  return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
-                                                         (LONG)n, (LONG)o);
-#endif
-}
-
-static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
-#ifdef GPR_ARCH_64
-  return o == (gpr_atm)InterlockedCompareExchangeRelease64(
-                  (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
-#else
-  return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG *)p,
-                                                         (LONG)n, (LONG)o);
-#endif
-}
-
-static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p,
-                                                     gpr_atm delta) {
-  /* Use the CAS operation to get pointer-sized fetch and add */
-  gpr_atm old;
-  do {
-    old = *p;
-  } while (!gpr_atm_no_barrier_cas(p, old, old + delta));
-  return old;
-}
-
-static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta) {
-  /* Use a CAS operation to get pointer-sized fetch and add */
-  gpr_atm old;
-#ifdef GPR_ARCH_64
-  do {
-    old = *p;
-  } while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG *)p,
-                                                        (LONGLONG)old + delta,
-                                                        (LONGLONG)old));
-#else
-  do {
-    old = *p;
-  } while (old != (gpr_atm)InterlockedCompareExchange(
-                      (volatile LONG *)p, (LONG)old + delta, (LONG)old));
-#endif
-  return old;
-}
+#include <grpc/impl/codegen/atm_win32.h>
 
 #endif /* GRPC_SUPPORT_ATM_WIN32_H */
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index 59db4ba..3fdba04 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -34,75 +34,6 @@
 #ifndef GRPC_SUPPORT_LOG_H
 #define GRPC_SUPPORT_LOG_H
 
-#include <stdlib.h> /* for abort() */
-#include <stdarg.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* GPR log API.
-
-   Usage (within grpc):
-
-   int argument1 = 3;
-   char* argument2 = "hello";
-   gpr_log(GPR_DEBUG, "format string %d", argument1);
-   gpr_log(GPR_INFO, "hello world");
-   gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
-
-/* The severity of a log message - use the #defines below when calling into
-   gpr_log to additionally supply file and line data */
-typedef enum gpr_log_severity {
-  GPR_LOG_SEVERITY_DEBUG,
-  GPR_LOG_SEVERITY_INFO,
-  GPR_LOG_SEVERITY_ERROR
-} gpr_log_severity;
-
-/* Returns a string representation of the log severity */
-const char *gpr_log_severity_string(gpr_log_severity severity);
-
-/* Macros to build log contexts at various severity levels */
-#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
-#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
-#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
-
-/* Log a message. It's advised to use GPR_xxx above to generate the context
- * for each message */
-void gpr_log(const char *file, int line, gpr_log_severity severity,
-             const char *format, ...);
-
-void gpr_log_message(const char *file, int line, gpr_log_severity severity,
-                     const char *message);
-
-/* Log overrides: applications can use this API to intercept logging calls
-   and use their own implementations */
-
-typedef struct {
-  const char *file;
-  int line;
-  gpr_log_severity severity;
-  const char *message;
-} gpr_log_func_args;
-
-typedef void (*gpr_log_func)(gpr_log_func_args *args);
-void gpr_set_log_function(gpr_log_func func);
-
-/* abort() the process if x is zero, having written a line to the log.
-
-   Intended for internal invariants.  If the error can be recovered from,
-   without the possibility of corruption, or might best be reflected via
-   an exception in a higher-level language, consider returning error code.  */
-#define GPR_ASSERT(x)                                 \
-  do {                                                \
-    if (!(x)) {                                       \
-      gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
-      abort();                                        \
-    }                                                 \
-  } while (0)
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/log.h>
 
 #endif /* GRPC_SUPPORT_LOG_H */
diff --git a/include/grpc/support/slice.h b/include/grpc/support/slice.h
index 26ca9a8..b45db03 100644
--- a/include/grpc/support/slice.h
+++ b/include/grpc/support/slice.h
@@ -34,149 +34,6 @@
 #ifndef GRPC_SUPPORT_SLICE_H
 #define GRPC_SUPPORT_SLICE_H
 
-#include <grpc/support/sync.h>
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Slice API
-
-   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.
-
-   The data-structure for slices is exposed here to allow non-gpr code to
-   build slices from whatever data they have available.
-
-   When defining interfaces that handle slices, care should be taken to define
-   reference ownership semantics (who should call unref?) and mutability
-   constraints (is the callee allowed to modify the slice?) */
-
-/* Reference count container for gpr_slice. Contains function pointers to
-   increment and decrement reference counts. Implementations should cleanup
-   when the reference count drops to zero.
-   Typically client code should not touch this, and use gpr_slice_malloc,
-   gpr_slice_new, or gpr_slice_new_with_len instead. */
-typedef struct gpr_slice_refcount {
-  void (*ref)(void *);
-  void (*unref)(void *);
-} gpr_slice_refcount;
-
-#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
-
-/* A gpr_slice s, if initialized, represents the byte range
-   s.bytes[0..s.length-1].
-
-   It can have an associated ref count which has a destruction routine to be run
-   when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()).
-   Multiple gpr_slice values may share a ref count.
-
-   If the slice does not have a refcount, it represents an inlined small piece
-   of data that is copied by value. */
-typedef struct gpr_slice {
-  struct gpr_slice_refcount *refcount;
-  union {
-    struct {
-      uint8_t *bytes;
-      size_t length;
-    } refcounted;
-    struct {
-      uint8_t length;
-      uint8_t bytes[GPR_SLICE_INLINED_SIZE];
-    } inlined;
-  } data;
-} gpr_slice;
-
-#define GPR_SLICE_START_PTR(slice)                  \
-  ((slice).refcount ? (slice).data.refcounted.bytes \
-                    : (slice).data.inlined.bytes)
-#define GPR_SLICE_LENGTH(slice)                      \
-  ((slice).refcount ? (slice).data.refcounted.length \
-                    : (slice).data.inlined.length)
-#define GPR_SLICE_SET_LENGTH(slice, newlen)                               \
-  ((slice).refcount ? ((slice).data.refcounted.length = (size_t)(newlen)) \
-                    : ((slice).data.inlined.length = (uint8_t)(newlen)))
-#define GPR_SLICE_END_PTR(slice) \
-  GPR_SLICE_START_PTR(slice) + GPR_SLICE_LENGTH(slice)
-#define GPR_SLICE_IS_EMPTY(slice) (GPR_SLICE_LENGTH(slice) == 0)
-
-/* Increment the refcount of s. Requires slice is initialized.
-   Returns s. */
-gpr_slice gpr_slice_ref(gpr_slice s);
-
-/* Decrement the ref count of s.  If the ref count of s reaches zero, all
-   slices sharing the ref count are destroyed, and considered no longer
-   initialized.  If s is ultimately derived from a call to gpr_slice_new(start,
-   len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is
-   ultimately derived from a call to gpr_slice_new_with_len(start, len, dest)
-   where dest!=NULL , then (*dest)(start, len).  Requires s initialized.  */
-void gpr_slice_unref(gpr_slice s);
-
-/* Create a slice pointing at some data. Calls malloc to allocate a refcount
-   for the object, and arranges that destroy will be called with the pointer
-   passed in at destruction. */
-gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
-
-/* Equivalent to gpr_slice_new, but with a two argument destroy function that
-   also takes the slice length. */
-gpr_slice gpr_slice_new_with_len(void *p, size_t len,
-                                 void (*destroy)(void *, size_t));
-
-/* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
-   call.
-   Aborts if malloc() fails. */
-gpr_slice gpr_slice_malloc(size_t length);
-
-/* Create a slice by copying a string.
-   Does not preserve null terminators.
-   Equivalent to:
-     size_t len = strlen(source);
-     gpr_slice slice = gpr_slice_malloc(len);
-     memcpy(slice->data, source, len); */
-gpr_slice gpr_slice_from_copied_string(const char *source);
-
-/* Create a slice by copying a buffer.
-   Equivalent to:
-     gpr_slice slice = gpr_slice_malloc(len);
-     memcpy(slice->data, source, len); */
-gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
-
-/* Create a slice pointing to constant memory */
-gpr_slice gpr_slice_from_static_string(const char *source);
-
-/* Return a result slice derived from s, which shares a ref count with s, where
-   result.data==s.data+begin, and result.length==end-begin.
-   The ref count of s is increased by one.
-   Requires s initialized, begin <= end, begin <= s.length, and
-   end <= source->length. */
-gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
-
-/* The same as gpr_slice_sub, but without altering the ref count */
-gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
-
-/* Splits s into two: modifies s to be s[0:split], and returns a new slice,
-   sharing a refcount with s, that contains s[split:s.length].
-   Requires s intialized, split <= s.length */
-gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
-
-/* Splits s into two: modifies s to be s[split:s.length], and returns a new
-   slice, sharing a refcount with s, that contains s[0:split].
-   Requires s intialized, split <= s.length */
-gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
-
-gpr_slice gpr_empty_slice(void);
-
-/* Returns <0 if a < b, ==0 if a == b, >0 if a > b
-   The order is arbitrary, and is not guaranteed to be stable across different
-   versions of the API. */
-int gpr_slice_cmp(gpr_slice a, gpr_slice b);
-int gpr_slice_str_cmp(gpr_slice a, const char *b);
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/slice.h>
 
 #endif /* GRPC_SUPPORT_SLICE_H */
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h
index 99f3881..cf7a89f 100644
--- a/include/grpc/support/slice_buffer.h
+++ b/include/grpc/support/slice_buffer.h
@@ -34,69 +34,6 @@
 #ifndef GRPC_SUPPORT_SLICE_BUFFER_H
 #define GRPC_SUPPORT_SLICE_BUFFER_H
 
-#include <grpc/support/slice.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
-
-/* Represents an expandable array of slices, to be interpreted as a single item
-   TODO(ctiller): inline some small number of elements into the struct, to
-                  avoid per-call allocations */
-typedef struct {
-  /* slices in the array */
-  gpr_slice *slices;
-  /* the number of slices in the array */
-  size_t count;
-  /* the number of slices allocated in the array */
-  size_t capacity;
-  /* the combined length of all slices in the array */
-  size_t length;
-  /* inlined elements to avoid allocations */
-  gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS];
-} gpr_slice_buffer;
-
-/* initialize a slice buffer */
-void gpr_slice_buffer_init(gpr_slice_buffer *sb);
-/* destroy a slice buffer - unrefs any held elements */
-void gpr_slice_buffer_destroy(gpr_slice_buffer *sb);
-/* Add an element to a slice buffer - takes ownership of the slice.
-   This function is allowed to concatenate the passed in slice to the end of
-   some other slice if desired by the slice buffer. */
-void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice);
-/* add an element to a slice buffer - takes ownership of the slice and returns
-   the index of the slice.
-   Guarantees that the slice will not be concatenated at the end of another
-   slice (i.e. the data for this slice will begin at the first byte of the
-   slice at the returned index in sb->slices)
-   The implementation MAY decide to concatenate data at the end of a small
-   slice added in this fashion. */
-size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice slice);
-void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices, size_t n);
-/* add a very small (less than 8 bytes) amount of data to the end of a slice
-   buffer: returns a pointer into which to add the data */
-uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len);
-/* pop the last buffer, but don't unref it */
-void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
-/* clear a slice buffer, unref all elements */
-void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb);
-/* swap the contents of two slice buffers */
-void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b);
-/* move all of the elements of src into dst */
-void gpr_slice_buffer_move_into(gpr_slice_buffer *src, gpr_slice_buffer *dst);
-/* remove n bytes from the end of a slice buffer */
-void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n,
-                               gpr_slice_buffer *garbage);
-/* move the first n bytes of src into dst */
-void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n,
-                                 gpr_slice_buffer *dst);
-/* take the first slice in the slice buffer */
-gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src);
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/slice_buffer.h>
 
 #endif /* GRPC_SUPPORT_SLICE_BUFFER_H */
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index 4f42cff..a014580 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -33,283 +33,7 @@
 
 #ifndef GRPC_SUPPORT_SYNC_H
 #define GRPC_SUPPORT_SYNC_H
-/* Synchronization primitives for GPR.
 
-   The type  gpr_mu              provides a non-reentrant mutex (lock).
-
-   The type  gpr_cv              provides a condition variable.
-
-   The type  gpr_once            provides for one-time initialization.
-
-   The type gpr_event            provides one-time-setting, reading, and
-                                 waiting of a void*, with memory barriers.
-
-   The type gpr_refcount         provides an object reference counter,
-                                 with memory barriers suitable to control
-                                 object lifetimes.
-
-   The type gpr_stats_counter    provides an atomic statistics counter. It
-                                 provides no memory barriers.
- */
-
-/* Platform-specific type declarations of gpr_mu and gpr_cv.   */
-#include <grpc/support/port_platform.h>
-#include <grpc/support/sync_generic.h>
-
-#if defined(GPR_POSIX_SYNC)
-#include <grpc/support/sync_posix.h>
-#elif defined(GPR_WIN32)
-#include <grpc/support/sync_win32.h>
-#elif !defined(GPR_CUSTOM_SYNC)
-#error Unable to determine platform for sync
-#endif
-
-#include <grpc/support/time.h> /* for gpr_timespec */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* --- Mutex interface ---
-
-   At most one thread may hold an exclusive lock on a mutex at any given time.
-   Actions taken by a thread that holds a mutex exclusively happen after
-   actions taken by all previous holders of the mutex.  Variables of type
-   gpr_mu are uninitialized when first declared.  */
-
-/* Initialize *mu.  Requires:  *mu uninitialized.  */
-void gpr_mu_init(gpr_mu *mu);
-
-/* Cause *mu no longer to be initialized, freeing any memory in use.  Requires:
-   *mu initialized; no other concurrent operation on *mu.  */
-void gpr_mu_destroy(gpr_mu *mu);
-
-/* Wait until no thread has a lock on *mu, cause the calling thread to own an
-   exclusive lock on *mu, then return.  May block indefinitely or crash if the
-   calling thread has a lock on *mu.  Requires:  *mu initialized.  */
-void gpr_mu_lock(gpr_mu *mu);
-
-/* Release an exclusive lock on *mu held by the calling thread.  Requires:  *mu
-   initialized; the calling thread holds an exclusive lock on *mu.  */
-void gpr_mu_unlock(gpr_mu *mu);
-
-/* Without blocking, attempt to acquire an exclusive lock on *mu for the
-   calling thread, then return non-zero iff success.  Fail, if any thread holds
-   the lock; succeeds with high probability if no thread holds the lock.
-   Requires:  *mu initialized.  */
-int gpr_mu_trylock(gpr_mu *mu);
-
-/* --- Condition variable interface ---
-
-   A while-loop should be used with gpr_cv_wait() when waiting for conditions
-   to become true.  See the example below.  Variables of type gpr_cv are
-   uninitialized when first declared.  */
-
-/* Initialize *cv.  Requires:  *cv uninitialized.  */
-void gpr_cv_init(gpr_cv *cv);
-
-/* Cause *cv no longer to be initialized, freeing any memory in use.  Requires:
-   *cv initialized; no other concurrent operation on *cv.*/
-void gpr_cv_destroy(gpr_cv *cv);
-
-/* Atomically release *mu and wait on *cv.  When the calling thread is woken
-   from *cv or the deadline abs_deadline is exceeded, execute gpr_mu_lock(mu)
-   and return whether the deadline was exceeded.  Use
-   abs_deadline==gpr_inf_future for no deadline.  May return even when not
-   woken explicitly.  Requires:  *mu and *cv initialized; the calling thread
-   holds an exclusive lock on *mu.  */
-int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
-
-/* If any threads are waiting on *cv, wake at least one.
-   Clients may treat this as an optimization of gpr_cv_broadcast()
-   for use in the case where waking more than one waiter is not useful.
-   Requires:  *cv initialized.  */
-void gpr_cv_signal(gpr_cv *cv);
-
-/* Wake all threads waiting on *cv.  Requires:  *cv initialized.  */
-void gpr_cv_broadcast(gpr_cv *cv);
-
-/* --- One-time initialization ---
-
-   gpr_once must be declared with static storage class, and initialized with
-   GPR_ONCE_INIT.  e.g.,
-     static gpr_once once_var = GPR_ONCE_INIT;     */
-
-/* Ensure that (*init_routine)() has been called exactly once (for the
-   specified gpr_once instance) and then return.
-   If multiple threads call gpr_once() on the same gpr_once instance, one of
-   them will call (*init_routine)(), and the others will block until that call
-   finishes.*/
-void gpr_once_init(gpr_once *once, void (*init_routine)(void));
-
-/* --- One-time event notification ---
-
-  These operations act on a gpr_event, which should be initialized with
-  gpr_ev_init(), or with GPR_EVENT_INIT if static, e.g.,
-       static gpr_event event_var = GPR_EVENT_INIT;
-  It requires no destruction.  */
-
-/* Initialize *ev. */
-void gpr_event_init(gpr_event *ev);
-
-/* Set *ev so that gpr_event_get() and gpr_event_wait() will return value.
-   Requires:  *ev initialized; value != NULL; no prior or concurrent calls to
-   gpr_event_set(ev, ...) since initialization.  */
-void gpr_event_set(gpr_event *ev, void *value);
-
-/* Return the value set by gpr_event_set(ev, ...), or NULL if no such call has
-   completed.  If the result is non-NULL, all operations that occurred prior to
-   the gpr_event_set(ev, ...) set will be visible after this call returns.
-   Requires:  *ev initialized.  This operation is faster than acquiring a mutex
-   on most platforms.  */
-void *gpr_event_get(gpr_event *ev);
-
-/* Wait until *ev is set by gpr_event_set(ev, ...), or abs_deadline is
-   exceeded, then return gpr_event_get(ev).  Requires:  *ev initialized.  Use
-   abs_deadline==gpr_inf_future for no deadline.  When the event has been
-   signalled before the call, this operation is faster than acquiring a mutex
-   on most platforms.  */
-void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
-
-/* --- Reference counting ---
-
-   These calls act on the type gpr_refcount.  It requires no destruction.  */
-
-/* Initialize *r to value n.  */
-void gpr_ref_init(gpr_refcount *r, int n);
-
-/* Increment the reference count *r.  Requires *r initialized. */
-void gpr_ref(gpr_refcount *r);
-
-/* Increment the reference count *r by n.  Requires *r initialized, n > 0. */
-void gpr_refn(gpr_refcount *r, int n);
-
-/* Decrement the reference count *r and return non-zero iff it has reached
-   zero. .  Requires *r initialized. */
-int gpr_unref(gpr_refcount *r);
-
-/* --- Stats counters ---
-
-   These calls act on the integral type gpr_stats_counter.  It requires no
-   destruction.  Static instances may be initialized with
-       gpr_stats_counter c = GPR_STATS_INIT;
-   Beware:  These operations do not imply memory barriers.  Do not use them to
-   synchronize other events.  */
-
-/* Initialize *c to the value n. */
-void gpr_stats_init(gpr_stats_counter *c, intptr_t n);
-
-/* *c += inc.  Requires: *c initialized. */
-void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc);
-
-/* Return *c.  Requires: *c initialized. */
-intptr_t gpr_stats_read(const gpr_stats_counter *c);
-
-/* ==================Example use of interface===================
-   A producer-consumer queue of up to N integers,
-   illustrating the use of the calls in this interface. */
-#if 0
-
-#define N 4
-
-   typedef struct queue {
-     gpr_cv non_empty;  /* Signalled when length becomes non-zero. */
-     gpr_cv non_full;   /* Signalled when length becomes non-N. */
-     gpr_mu mu;         /* Protects all fields below.
-                            (That is, except during initialization or
-                            destruction, the fields below should be accessed
-                            only by a thread that holds mu.) */
-     int head;           /* Index of head of queue 0..N-1. */
-     int length;         /* Number of valid elements in queue 0..N. */
-     int elem[N];        /* elem[head .. head+length-1] are queue elements. */
-   } queue;
-
-   /* Initialize *q. */
-   void queue_init(queue *q) {
-     gpr_mu_init(&q->mu);
-     gpr_cv_init(&q->non_empty);
-     gpr_cv_init(&q->non_full);
-     q->head = 0;
-     q->length = 0;
-   }
-
-   /* Free storage associated with *q. */
-   void queue_destroy(queue *q) {
-     gpr_mu_destroy(&q->mu);
-     gpr_cv_destroy(&q->non_empty);
-     gpr_cv_destroy(&q->non_full);
-   }
-
-   /* Wait until there is room in *q, then append x to *q. */
-   void queue_append(queue *q, int x) {
-     gpr_mu_lock(&q->mu);
-     /* To wait for a predicate without a deadline, loop on the negation of the
-        predicate, and use gpr_cv_wait(..., gpr_inf_future) inside the loop
-        to release the lock, wait, and reacquire on each iteration.  Code that
-        makes the condition true should use gpr_cv_broadcast() on the
-        corresponding condition variable.  The predicate must be on state
-        protected by the lock.  */
-     while (q->length == N) {
-       gpr_cv_wait(&q->non_full, &q->mu, gpr_inf_future);
-     }
-     if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
-       /* It's normal to use gpr_cv_broadcast() or gpr_signal() while
-          holding the lock. */
-       gpr_cv_broadcast(&q->non_empty);
-     }
-     q->elem[(q->head + q->length) % N] = x;
-     q->length++;
-     gpr_mu_unlock(&q->mu);
-   }
-
-   /* If it can be done without blocking, append x to *q and return non-zero.
-      Otherwise return 0. */
-   int queue_try_append(queue *q, int x) {
-     int result = 0;
-     if (gpr_mu_trylock(&q->mu)) {
-       if (q->length != N) {
-         if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
-           gpr_cv_broadcast(&q->non_empty);
-         }
-         q->elem[(q->head + q->length) % N] = x;
-         q->length++;
-         result = 1;
-       }
-       gpr_mu_unlock(&q->mu);
-     }
-     return result;
-   }
-
-   /* Wait until the *q is non-empty or deadline abs_deadline passes.  If the
-      queue is non-empty, remove its head entry, place it in *head, and return
-      non-zero.  Otherwise return 0.  */
-   int queue_remove(queue *q, int *head, gpr_timespec abs_deadline) {
-     int result = 0;
-     gpr_mu_lock(&q->mu);
-     /* To wait for a predicate with a deadline, loop on the negation of the
-        predicate or until gpr_cv_wait() returns true.  Code that makes
-        the condition true should use gpr_cv_broadcast() on the corresponding
-        condition variable.  The predicate must be on state protected by the
-        lock. */
-     while (q->length == 0 &&
-            !gpr_cv_wait(&q->non_empty, &q->mu, abs_deadline)) {
-     }
-     if (q->length != 0) {    /* Queue is non-empty. */
-       result = 1;
-       if (q->length == N) {  /* Wake threads blocked in queue_append(). */
-         gpr_cv_broadcast(&q->non_full);
-       }
-       *head = q->elem[q->head];
-       q->head = (q->head + 1) % N;
-       q->length--;
-     } /* else deadline exceeded */
-     gpr_mu_unlock(&q->mu);
-     return result;
-   }
-#endif /* 0 */
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/sync.h>
 
 #endif /* GRPC_SUPPORT_SYNC_H */
diff --git a/include/grpc/support/sync_generic.h b/include/grpc/support/sync_generic.h
index fd55e02..d74b5d8 100644
--- a/include/grpc/support/sync_generic.h
+++ b/include/grpc/support/sync_generic.h
@@ -33,23 +33,7 @@
 
 #ifndef GRPC_SUPPORT_SYNC_GENERIC_H
 #define GRPC_SUPPORT_SYNC_GENERIC_H
-/* Generic type defintions for gpr_sync. */
 
-#include <grpc/support/atm.h>
-
-/* gpr_event */
-typedef struct { gpr_atm state; } gpr_event;
-
-#define GPR_EVENT_INIT \
-  { 0 }
-
-/* gpr_refcount */
-typedef struct { gpr_atm count; } gpr_refcount;
-
-/* gpr_stats_counter */
-typedef struct { gpr_atm value; } gpr_stats_counter;
-
-#define GPR_STATS_INIT \
-  { 0 }
+#include <grpc/impl/codegen/sync_generic.h>
 
 #endif /* GRPC_SUPPORT_SYNC_GENERIC_H */
diff --git a/include/grpc/support/sync_posix.h b/include/grpc/support/sync_posix.h
index 81ffa25..19aca03 100644
--- a/include/grpc/support/sync_posix.h
+++ b/include/grpc/support/sync_posix.h
@@ -34,14 +34,6 @@
 #ifndef GRPC_SUPPORT_SYNC_POSIX_H
 #define GRPC_SUPPORT_SYNC_POSIX_H
 
-#include <grpc/support/sync_generic.h>
-
-#include <pthread.h>
-
-typedef pthread_mutex_t gpr_mu;
-typedef pthread_cond_t gpr_cv;
-typedef pthread_once_t gpr_once;
-
-#define GPR_ONCE_INIT PTHREAD_ONCE_INIT
+#include <grpc/impl/codegen/sync_posix.h>
 
 #endif /* GRPC_SUPPORT_SYNC_POSIX_H */
diff --git a/include/grpc/support/sync_win32.h b/include/grpc/support/sync_win32.h
index 8ddbeaa..5631c52 100644
--- a/include/grpc/support/sync_win32.h
+++ b/include/grpc/support/sync_win32.h
@@ -34,16 +34,6 @@
 #ifndef GRPC_SUPPORT_SYNC_WIN32_H
 #define GRPC_SUPPORT_SYNC_WIN32_H
 
-#include <grpc/support/sync_generic.h>
-
-typedef struct {
-  CRITICAL_SECTION cs; /* Not an SRWLock until Vista is unsupported */
-  int locked;
-} gpr_mu;
-
-typedef CONDITION_VARIABLE gpr_cv;
-
-typedef INIT_ONCE gpr_once;
-#define GPR_ONCE_INIT INIT_ONCE_STATIC_INIT
+#include <grpc/impl/codegen/sync_win32.h>
 
 #endif /* GRPC_SUPPORT_SYNC_WIN32_H */