From 9abac80147546893610c8b3553c1b3ea6a08d122 Mon Sep 17 00:00:00 2001
From: root <root@sipproxy-07.90e9.com>
Date: Mon, 10 Nov 2014 09:21:30 +0000
Subject: [PATCH] resolve builds

---
 modules/kazoo/Makefile                    |   27 +-
 modules/kazoo/deps/Makefile               |   18 +
 modules/kazoo/deps/amqp.h                 | 2352 +++++++++++++++++++++++++++++
 modules/kazoo/deps/amqp_api.c             |  340 +++++
 modules/kazoo/deps/amqp_connection.c      |  535 +++++++
 modules/kazoo/deps/amqp_consumer.c        |  308 ++++
 modules/kazoo/deps/amqp_framing.c         | 2102 ++++++++++++++++++++++++++
 modules/kazoo/deps/amqp_framing.h         |  640 ++++++++
 modules/kazoo/deps/amqp_hostcheck.c       |  201 +++
 modules/kazoo/deps/amqp_hostcheck.h       |   36 +
 modules/kazoo/deps/amqp_mem.c             |  252 ++++
 modules/kazoo/deps/amqp_openssl.c         |  626 ++++++++
 modules/kazoo/deps/amqp_private.h         |  363 +++++
 modules/kazoo/deps/amqp_socket.c          | 1388 +++++++++++++++++
 modules/kazoo/deps/amqp_socket.h          |  195 +++
 modules/kazoo/deps/amqp_ssl_socket.h      |  168 +++
 modules/kazoo/deps/amqp_table.c           |  614 ++++++++
 modules/kazoo/deps/amqp_tcp_socket.c      |  303 ++++
 modules/kazoo/deps/amqp_tcp_socket.h      |   73 +
 modules/kazoo/deps/amqp_timer.c           |  140 ++
 modules/kazoo/deps/amqp_timer.h           |   67 +
 modules/kazoo/deps/amqp_url.c             |  218 +++
 modules/kazoo/deps/arraylist.c            |  101 ++
 modules/kazoo/deps/arraylist.h            |   56 +
 modules/kazoo/deps/bits.h                 |   28 +
 modules/kazoo/deps/config.h               |  209 +++
 modules/kazoo/deps/debug.c                |   83 +
 modules/kazoo/deps/debug.h                |   71 +
 modules/kazoo/deps/json.h                 |   34 +
 modules/kazoo/deps/json_c_version.c       |   20 +
 modules/kazoo/deps/json_c_version.h       |   22 +
 modules/kazoo/deps/json_config.h          |    4 +
 modules/kazoo/deps/json_inttypes.h        |   28 +
 modules/kazoo/deps/json_object.c          |  855 +++++++++++
 modules/kazoo/deps/json_object.h          |  612 ++++++++
 modules/kazoo/deps/json_object_iterator.c |  168 +++
 modules/kazoo/deps/json_object_iterator.h |  239 +++
 modules/kazoo/deps/json_object_private.h  |   47 +
 modules/kazoo/deps/json_tokener.c         |  888 +++++++++++
 modules/kazoo/deps/json_tokener.h         |  208 +++
 modules/kazoo/deps/json_util.c            |  300 ++++
 modules/kazoo/deps/json_util.h            |   41 +
 modules/kazoo/deps/libjson.c              |   26 +
 modules/kazoo/deps/linkhash.c             |  602 ++++++++
 modules/kazoo/deps/linkhash.h             |  292 ++++
 modules/kazoo/deps/math_compat.h          |   28 +
 modules/kazoo/deps/printbuf.c             |  192 +++
 modules/kazoo/deps/printbuf.h             |   77 +
 modules/kazoo/deps/random_seed.c          |  237 +++
 modules/kazoo/deps/random_seed.h          |   25 +
 modules/kazoo/deps/threads.h              |   29 +
 modules/kazoo/kz_amqp.c                   |   10 +-
 modules/kazoo/kz_pua.c                    |    3 +-
 53 files changed, 16470 insertions(+), 31 deletions(-)
 create mode 100644 modules/kazoo/deps/Makefile
 create mode 100644 modules/kazoo/deps/amqp.h
 create mode 100644 modules/kazoo/deps/amqp_api.c
 create mode 100644 modules/kazoo/deps/amqp_connection.c
 create mode 100644 modules/kazoo/deps/amqp_consumer.c
 create mode 100644 modules/kazoo/deps/amqp_framing.c
 create mode 100644 modules/kazoo/deps/amqp_framing.h
 create mode 100644 modules/kazoo/deps/amqp_hostcheck.c
 create mode 100644 modules/kazoo/deps/amqp_hostcheck.h
 create mode 100644 modules/kazoo/deps/amqp_mem.c
 create mode 100644 modules/kazoo/deps/amqp_openssl.c
 create mode 100644 modules/kazoo/deps/amqp_private.h
 create mode 100644 modules/kazoo/deps/amqp_socket.c
 create mode 100644 modules/kazoo/deps/amqp_socket.h
 create mode 100644 modules/kazoo/deps/amqp_ssl_socket.h
 create mode 100644 modules/kazoo/deps/amqp_table.c
 create mode 100644 modules/kazoo/deps/amqp_tcp_socket.c
 create mode 100644 modules/kazoo/deps/amqp_tcp_socket.h
 create mode 100644 modules/kazoo/deps/amqp_timer.c
 create mode 100644 modules/kazoo/deps/amqp_timer.h
 create mode 100644 modules/kazoo/deps/amqp_url.c
 create mode 100644 modules/kazoo/deps/arraylist.c
 create mode 100644 modules/kazoo/deps/arraylist.h
 create mode 100644 modules/kazoo/deps/bits.h
 create mode 100644 modules/kazoo/deps/config.h
 create mode 100644 modules/kazoo/deps/debug.c
 create mode 100644 modules/kazoo/deps/debug.h
 create mode 100644 modules/kazoo/deps/json.h
 create mode 100644 modules/kazoo/deps/json_c_version.c
 create mode 100644 modules/kazoo/deps/json_c_version.h
 create mode 100644 modules/kazoo/deps/json_config.h
 create mode 100644 modules/kazoo/deps/json_inttypes.h
 create mode 100644 modules/kazoo/deps/json_object.c
 create mode 100644 modules/kazoo/deps/json_object.h
 create mode 100644 modules/kazoo/deps/json_object_iterator.c
 create mode 100644 modules/kazoo/deps/json_object_iterator.h
 create mode 100644 modules/kazoo/deps/json_object_private.h
 create mode 100644 modules/kazoo/deps/json_tokener.c
 create mode 100644 modules/kazoo/deps/json_tokener.h
 create mode 100644 modules/kazoo/deps/json_util.c
 create mode 100644 modules/kazoo/deps/json_util.h
 create mode 100644 modules/kazoo/deps/libjson.c
 create mode 100644 modules/kazoo/deps/linkhash.c
 create mode 100644 modules/kazoo/deps/linkhash.h
 create mode 100644 modules/kazoo/deps/math_compat.h
 create mode 100644 modules/kazoo/deps/printbuf.c
 create mode 100644 modules/kazoo/deps/printbuf.h
 create mode 100644 modules/kazoo/deps/random_seed.c
 create mode 100644 modules/kazoo/deps/random_seed.h
 create mode 100644 modules/kazoo/deps/threads.h

diff --git a/modules/kazoo/Makefile b/modules/kazoo/Makefile
index 853566c..196b584 100644
--- a/modules/kazoo/Makefile
+++ b/modules/kazoo/Makefile
@@ -5,31 +5,9 @@
 include ../../Makefile.defs
 auto_gen=
 NAME=kazoo.so
-JLIB=json
 
-BUILDER = $(shell which pkg-config)
-ifeq ($(BUILDER),)
-	JSONC=$(shell ls $(SYSBASE)/include/lib/libjson*.so $(LOCALBASE)/lib/libjson*.so 2>/dev/null | grep json-c)
-else
-	JSONC=$(shell pkg-config --libs json-c 2>/dev/null | grep json-c)
-endif
-
-ifneq ($(JSONC),)
-	JLIB=json-c
-endif
-
-ifeq ($(BUILDER),)
-	DEFS+=-I$(LOCALBASE)/include -I$(SYSBASE)/include \
-		-I$(SYSBASE)/include/$(JLIB)
-	LIBS=-L$(LOCALBASE)/lib -I$(SYSBASE)/lib -lrabbitmq -l$(JLIB) -luuid
-else
-	DEFS += $(shell $(BUILDER) --cflags $(JLIB))
-	LIBS += $(shell $(BUILDER) --libs $(JLIB))
-	DEFS += $(shell $(BUILDER) --cflags uuid)
-	LIBS += $(shell $(BUILDER) --libs uuid)
-	DEFS += $(shell $(BUILDER) --cflags librabbitmq)
-	LIBS += $(shell $(BUILDER) --libs librabbitmq)
-endif
+DEFS+=-I$(CURDIR)/deps -I$(LOCALBASE)/include -I$(SYSBASE)/include 
+LIBS=-L$(LOCALBASE)/lib -I$(SYSBASE)/lib -luuid
 
 DEFS += -DKAMAILIO_MOD_INTERFACE
 
@@ -38,5 +16,6 @@ SERLIBPATH=../../lib
 SER_LIBS=$(SERLIBPATH)/srdb2/srdb2 $(SERLIBPATH)/srdb1/srdb1
 SER_LIBS+=$(SERLIBPATH)/kmi/kmi
 SER_LIBS+=$(SERLIBPATH)/kcore/kcore
+SER_LIBS+=$(CURDIR)/deps/kazoo-deps
 
 include ../../Makefile.modules
diff --git a/modules/kazoo/deps/Makefile b/modules/kazoo/deps/Makefile
new file mode 100644
index 0000000..be0170a
--- /dev/null
+++ b/modules/kazoo/deps/Makefile
@@ -0,0 +1,18 @@
+
+# example library makefile
+#
+
+COREPATH= ../../..
+
+include ../../../Makefile.defs
+auto_gen=
+NAME:=kazoo-deps
+MAJOR_VER=1
+MINOR_VER=0
+BUGFIX_VER=0
+DEFS+=-DSER -DHAVE_CONFIG_H
+LIBS+=-lrt -lssl -lcrypto
+INCLUDES=  -I$(CURDIR) -I$(CURDIR)/../../lib -I$(CURDIR)/../../.. 
+
+include ../../../Makefile.libs
+
diff --git a/modules/kazoo/deps/amqp.h b/modules/kazoo/deps/amqp.h
new file mode 100644
index 0000000..d85c160
--- /dev/null
+++ b/modules/kazoo/deps/amqp.h
@@ -0,0 +1,2352 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/** \file */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2014
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifndef AMQP_H
+#define AMQP_H
+
+/** \cond HIDE_FROM_DOXYGEN */
+
+#ifdef __cplusplus
+#define AMQP_BEGIN_DECLS extern "C" {
+#define AMQP_END_DECLS }
+#else
+#define AMQP_BEGIN_DECLS
+#define AMQP_END_DECLS
+#endif
+
+/*
+ * \internal
+ * Important API decorators:
+ *  AMQP_PUBLIC_FUNCTION - a public API function
+ *  AMQP_PUBLIC_VARIABLE - a public API external variable
+ *  AMQP_CALL - calling convension (used on Win32)
+ */
+
+#if defined(_WIN32) && defined(_MSC_VER)
+# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
+#  define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
+#  define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern
+# else
+#  define AMQP_PUBLIC_FUNCTION
+#  if !defined(AMQP_STATIC)
+#   define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
+#  else
+#   define AMQP_PUBLIC_VARIABLE extern
+#  endif
+# endif
+# define AMQP_CALL __cdecl
+
+#elif defined(_WIN32) && defined(__BORLANDC__)
+# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
+#  define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
+#  define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern
+# else
+#  define AMQP_PUBLIC_FUNCTION
+#  if !defined(AMQP_STATIC)
+#   define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
+#  else
+#   define AMQP_PUBLIC_VARIABLE extern
+#  endif
+# endif
+# define AMQP_CALL __cdecl
+
+#elif defined(_WIN32) && defined(__MINGW32__)
+# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
+#  define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
+#  define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern
+# else
+#  define AMQP_PUBLIC_FUNCTION
+#  if !defined(AMQP_STATIC)
+#   define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
+#  else
+#   define AMQP_PUBLIC_VARIABLE extern
+#  endif
+# endif
+# define AMQP_CALL __cdecl
+
+#elif defined(_WIN32) && defined(__CYGWIN__)
+# if defined(AMQP_BUILD) && !defined(AMQP_STATIC)
+#  define AMQP_PUBLIC_FUNCTION __declspec(dllexport)
+#  define AMQP_PUBLIC_VARIABLE __declspec(dllexport)
+# else
+#  define AMQP_PUBLIC_FUNCTION
+#  if !defined(AMQP_STATIC)
+#   define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern
+#  else
+#   define AMQP_PUBLIC_VARIABLE extern
+#  endif
+# endif
+# define AMQP_CALL __cdecl
+
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define AMQP_PUBLIC_FUNCTION \
+  __attribute__ ((visibility ("default")))
+# define AMQP_PUBLIC_VARIABLE \
+  __attribute__ ((visibility ("default"))) extern
+# define AMQP_CALL
+#else
+# define AMQP_PUBLIC_FUNCTION
+# define AMQP_PUBLIC_VARIABLE extern
+# define AMQP_CALL
+#endif
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define AMQP_DEPRECATED(function) \
+  function __attribute__ ((__deprecated__))
+#elif defined(_MSC_VER)
+# define AMQP_DEPRECATED(function) \
+  __declspec(deprecated) function
+#else
+# define AMQP_DEPRECATED(function)
+#endif
+
+/* Define ssize_t on Win32/64 platforms
+   See: http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-April/030649.html for details
+   */
+#if !defined(_W64)
+#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#define _W64 __w64
+#else
+#define _W64
+#endif
+#endif
+
+#ifdef _MSC_VER
+#ifdef _WIN64
+typedef __int64 ssize_t;
+#else
+typedef _W64 int ssize_t;
+#endif
+#endif
+
+#if defined(_WIN32) && defined(__MINGW32__)
+#include <sys/types.h>
+#endif
+
+/** \endcond */
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct timeval;
+
+AMQP_BEGIN_DECLS
+
+/**
+ * \def AMQP_VERSION_MAJOR
+ *
+ * Major library version number compile-time constant
+ *
+ * The major version is incremented when backwards incompatible API changes
+ * are made.
+ *
+ * \sa AMQP_VERSION, AMQP_VERSION_STRING
+ *
+ * \since v0.4.0
+ */
+
+/**
+ * \def AMQP_VERSION_MINOR
+ *
+ * Minor library version number compile-time constant
+ *
+ * The minor version is incremented when new APIs are added. Existing APIs
+ * are left alone.
+ *
+ * \sa AMQP_VERSION, AMQP_VERSION_STRING
+ *
+ * \since v0.4.0
+ */
+
+/**
+ * \def AMQP_VERSION_PATCH
+ *
+ * Patch library version number compile-time constant
+ *
+ * The patch version is incremented when library code changes, but the API
+ * is not changed.
+ *
+ * \sa AMQP_VERSION, AMQP_VERSION_STRING
+ *
+ * \since v0.4.0
+ */
+
+/**
+ * \def AMQP_VERSION_IS_RELEASE
+ *
+ * Version constant set to 1 for tagged release, 0 otherwise
+ *
+ * NOTE: versions that are not tagged releases are not guaranteed to be API/ABI
+ * compatible with older releases, and may change commit-to-commit.
+ *
+ * \sa AMQP_VERSION, AMQP_VERSION_STRING
+ *
+ * \since v0.4.0
+ */
+/*
+ * Developer note: when changing these, be sure to update SOVERSION constants
+ *  in CMakeLists.txt and configure.ac
+ */
+
+#define AMQP_VERSION_MAJOR 0
+#define AMQP_VERSION_MINOR 5
+#define AMQP_VERSION_PATCH 2
+#define AMQP_VERSION_IS_RELEASE 1
+
+
+/**
+ * \def AMQP_VERSION
+ *
+ * Packed version number
+ *
+ * AMQP_VERSION is a 4-byte unsigned integer with the most significant byte
+ * set to AMQP_VERSION_MAJOR, the second most significant byte set to
+ * AMQP_VERSION_MINOR, third most significant byte set to AMQP_VERSION_PATCH,
+ * and the lowest byte set to AMQP_VERSION_IS_RELEASE.
+ *
+ * For example version 2.3.4 which is released version would be encoded as
+ * 0x02030401
+ *
+ * \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR,
+ *     AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE
+ *
+ * \since v0.4.0
+ */
+#define AMQP_VERSION ((AMQP_VERSION_MAJOR << 24) | \
+                      (AMQP_VERSION_MINOR << 16) | \
+                      (AMQP_VERSION_PATCH << 8)  | \
+                      (AMQP_VERSION_IS_RELEASE))
+
+/** \cond HIDE_FROM_DOXYGEN */
+#define AMQ_STRINGIFY(s) AMQ_STRINGIFY_HELPER(s)
+#define AMQ_STRINGIFY_HELPER(s) #s
+
+#define AMQ_VERSION_STRING  AMQ_STRINGIFY(AMQP_VERSION_MAJOR) "." \
+                            AMQ_STRINGIFY(AMQP_VERSION_MINOR) "." \
+                            AMQ_STRINGIFY(AMQP_VERSION_PATCH)
+/** \endcond */
+
+/**
+ * \def AMQP_VERSION_STRING
+ *
+ * Version string compile-time constant
+ *
+ * Non-released versions of the library will have "-pre" appended to the
+ * version string
+ *
+ * \sa amqp_version()
+ *
+ * \since v0.4.0
+ */
+#if AMQP_VERSION_IS_RELEASE
+# define AMQP_VERSION_STRING AMQ_VERSION_STRING
+#else
+# define AMQP_VERSION_STRING AMQ_VERSION_STRING "-pre"
+#endif
+
+
+/**
+ * Returns the rabbitmq-c version as a packed integer.
+ *
+ * See \ref AMQP_VERSION
+ *
+ * \return packed 32-bit integer representing version of library at runtime
+ *
+ * \sa AMQP_VERSION, amqp_version()
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+uint32_t
+AMQP_CALL amqp_version_number(void);
+
+/**
+ * Returns the rabbitmq-c version as a string.
+ *
+ * See \ref AMQP_VERSION_STRING
+ *
+ * \return a statically allocated string describing the version of rabbitmq-c.
+ *
+ * \sa amqp_version_number(), AMQP_VERSION_STRING, AMQP_VERSION
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+char const *
+AMQP_CALL amqp_version(void);
+
+/**
+ * \def AMQP_DEFAULT_FRAME_SIZE
+ *
+ * Default frame size (128Kb)
+ *
+ * \sa amqp_login(), amqp_login_with_properties()
+ *
+ * \since v0.4.0
+ */
+#define AMQP_DEFAULT_FRAME_SIZE 131072
+
+/**
+ * \def AMQP_DEFAULT_MAX_CHANNELS
+ *
+ * Default maximum number of channels (0, no limit)
+ *
+ * \sa amqp_login(), amqp_login_with_properties()
+ *
+ * \since v0.4.0
+ */
+#define AMQP_DEFAULT_MAX_CHANNELS 0
+
+/**
+ * \def AMQP_DEFAULT_HEARTBEAT
+ *
+ * Default heartbeat interval (0, heartbeat disabled)
+ *
+ * \sa amqp_login(), amqp_login_with_properties()
+ *
+ * \since v0.4.0
+ */
+#define AMQP_DEFAULT_HEARTBEAT 0
+
+/**
+ * boolean type 0 = false, true otherwise
+ *
+ * \since v0.1
+ */
+typedef int amqp_boolean_t;
+
+/**
+ * Method number
+ *
+ * \since v0.1
+ */
+typedef uint32_t amqp_method_number_t;
+
+/**
+ * Bitmask for flags
+ *
+ * \since v0.1
+ */
+typedef uint32_t amqp_flags_t;
+
+/**
+ * Channel type
+ *
+ * \since v0.1
+ */
+typedef uint16_t amqp_channel_t;
+
+/**
+ * Buffer descriptor
+ *
+ * \since v0.1
+ */
+typedef struct amqp_bytes_t_ {
+  size_t len;   /**< length of the buffer in bytes */
+  void *bytes;  /**< pointer to the beginning of the buffer */
+} amqp_bytes_t;
+
+/**
+ * Decimal data type
+ *
+ * \since v0.1
+ */
+typedef struct amqp_decimal_t_ {
+  uint8_t decimals;   /**< the location of the decimal point */
+  uint32_t value;     /**< the value before the decimal point is applied */
+} amqp_decimal_t;
+
+/**
+ * AMQP field table
+ *
+ * An AMQP field table is a set of key-value pairs.
+ * A key is a UTF-8 encoded string up to 128 bytes long, and are not null
+ * terminated.
+ * A value can be one of several different datatypes. \sa amqp_field_value_kind_t
+ *
+ * \sa amqp_table_entry_t
+ *
+ * \since v0.1
+ */
+typedef struct amqp_table_t_ {
+  int num_entries;                      /**< length of entries array */
+  struct amqp_table_entry_t_ *entries;  /**< an array of table entries */
+} amqp_table_t;
+
+/**
+ * An AMQP Field Array
+ *
+ * A repeated set of field values, all must be of the same type
+ *
+ * \since v0.1
+ */
+typedef struct amqp_array_t_ {
+  int num_entries;                      /**< Number of entries in the table */
+  struct amqp_field_value_t_ *entries;  /**< linked list of field values */
+} amqp_array_t;
+
+/*
+  0-9   0-9-1   Qpid/Rabbit  Type               Remarks
+---------------------------------------------------------------------------
+        t       t            Boolean
+        b       b            Signed 8-bit
+        B                    Unsigned 8-bit
+        U       s            Signed 16-bit      (A1)
+        u                    Unsigned 16-bit
+  I     I       I            Signed 32-bit
+        i                    Unsigned 32-bit
+        L       l            Signed 64-bit      (B)
+        l                    Unsigned 64-bit
+        f       f            32-bit float
+        d       d            64-bit float
+  D     D       D            Decimal
+        s                    Short string       (A2)
+  S     S       S            Long string
+        A                    Nested Array
+  T     T       T            Timestamp (u64)
+  F     F       F            Nested Table
+  V     V       V            Void
+                x            Byte array
+
+Remarks:
+
+ A1, A2: Notice how the types **CONFLICT** here. In Qpid and Rabbit,
+         's' means a signed 16-bit integer; in 0-9-1, it means a
+          short string.
+
+ B: Notice how the signednesses **CONFLICT** here. In Qpid and Rabbit,
+    'l' means a signed 64-bit integer; in 0-9-1, it means an unsigned
+    64-bit integer.
+
+I'm going with the Qpid/Rabbit types, where there's a conflict, and
+the 0-9-1 types otherwise. 0-8 is a subset of 0-9, which is a subset
+of the other two, so this will work for both 0-8 and 0-9-1 branches of
+the code.
+*/
+
+/**
+ * A field table value
+ *
+ * \since v0.1
+ */
+typedef struct amqp_field_value_t_ {
+  uint8_t kind;             /**< the type of the entry /sa amqp_field_value_kind_t */
+  union {
+    amqp_boolean_t boolean;   /**< boolean type AMQP_FIELD_KIND_BOOLEAN */
+    int8_t i8;                /**< int8_t type AMQP_FIELD_KIND_I8 */
+    uint8_t u8;               /**< uint8_t type AMQP_FIELD_KIND_U8 */
+    int16_t i16;              /**< int16_t type AMQP_FIELD_KIND_I16 */
+    uint16_t u16;             /**< uint16_t type AMQP_FIELD_KIND_U16 */
+    int32_t i32;              /**< int32_t type AMQP_FIELD_KIND_I32 */
+    uint32_t u32;             /**< uint32_t type AMQP_FIELD_KIND_U32 */
+    int64_t i64;              /**< int64_t type AMQP_FIELD_KIND_I64 */
+    uint64_t u64;             /**< uint64_t type AMQP_FIELD_KIND_U64, AMQP_FIELD_KIND_TIMESTAMP */
+    float f32;                /**< float type AMQP_FIELD_KIND_F32 */
+    double f64;               /**< double type AMQP_FIELD_KIND_F64 */
+    amqp_decimal_t decimal;   /**< amqp_decimal_t AMQP_FIELD_KIND_DECIMAL */
+    amqp_bytes_t bytes;       /**< amqp_bytes_t type AMQP_FIELD_KIND_UTF8, AMQP_FIELD_KIND_BYTES */
+    amqp_table_t table;       /**< amqp_table_t type AMQP_FIELD_KIND_TABLE */
+    amqp_array_t array;       /**< amqp_array_t type AMQP_FIELD_KIND_ARRAY */
+  } value;              /**< a union of the value */
+} amqp_field_value_t;
+
+/**
+ * An entry in a field-table
+ *
+ * \sa amqp_table_encode(), amqp_table_decode(), amqp_table_clone()
+ *
+ * \since v0.1
+ */
+typedef struct amqp_table_entry_t_ {
+  amqp_bytes_t key;           /**< the table entry key. Its a null-terminated UTF-8 string,
+                               * with a maximum size of 128 bytes */
+  amqp_field_value_t value;   /**< the table entry values */
+} amqp_table_entry_t;
+
+/**
+ * Field value types
+ *
+ * \since v0.1
+ */
+typedef enum {
+  AMQP_FIELD_KIND_BOOLEAN = 't',  /**< boolean type. 0 = false, 1 = true @see amqp_boolean_t */
+  AMQP_FIELD_KIND_I8 = 'b',       /**< 8-bit signed integer, datatype: int8_t */
+  AMQP_FIELD_KIND_U8 = 'B',       /**< 8-bit unsigned integer, datatype: uint8_t */
+  AMQP_FIELD_KIND_I16 = 's',      /**< 16-bit signed integer, datatype: int16_t */
+  AMQP_FIELD_KIND_U16 = 'u',      /**< 16-bit unsigned integer, datatype: uint16_t */
+  AMQP_FIELD_KIND_I32 = 'I',      /**< 32-bit signed integer, datatype: int32_t */
+  AMQP_FIELD_KIND_U32 = 'i',      /**< 32-bit unsigned integer, datatype: uint32_t */
+  AMQP_FIELD_KIND_I64 = 'l',      /**< 64-bit signed integer, datatype: int64_t */
+  AMQP_FIELD_KIND_U64 = 'L',      /**< 64-bit unsigned integer, datatype: uint64_t */
+  AMQP_FIELD_KIND_F32 = 'f',      /**< single-precision floating point value, datatype: float */
+  AMQP_FIELD_KIND_F64 = 'd',      /**< double-precision floating point value, datatype: double */
+  AMQP_FIELD_KIND_DECIMAL = 'D',  /**< amqp-decimal value, datatype: amqp_decimal_t */
+  AMQP_FIELD_KIND_UTF8 = 'S',     /**< UTF-8 null-terminated character string, datatype: amqp_bytes_t */
+  AMQP_FIELD_KIND_ARRAY = 'A',    /**< field array (repeated values of another datatype. datatype: amqp_array_t */
+  AMQP_FIELD_KIND_TIMESTAMP = 'T',/**< 64-bit timestamp. datatype uint64_t */
+  AMQP_FIELD_KIND_TABLE = 'F',    /**< field table. encapsulates a table inside a table entry. datatype: amqp_table_t */
+  AMQP_FIELD_KIND_VOID = 'V',     /**< empty entry */
+  AMQP_FIELD_KIND_BYTES = 'x'     /**< unformatted byte string, datatype: amqp_bytes_t */
+} amqp_field_value_kind_t;
+
+/**
+ * A list of allocation blocks
+ *
+ * \since v0.1
+ */
+typedef struct amqp_pool_blocklist_t_ {
+  int num_blocks;     /**< Number of blocks in the block list */
+  void **blocklist;   /**< Array of memory blocks */
+} amqp_pool_blocklist_t;
+
+/**
+ * A memory pool
+ *
+ * \since v0.1
+ */
+typedef struct amqp_pool_t_ {
+  size_t pagesize;            /**< the size of the page in bytes.
+                               *  allocations less than or equal to this size are
+                               *    allocated in the pages block list
+                               *  allocations greater than this are allocated in their
+                               *   own block in the large_blocks block list */
+
+  amqp_pool_blocklist_t pages;        /**< blocks that are the size of pagesize */
+  amqp_pool_blocklist_t large_blocks; /**< allocations larger than the pagesize */
+
+  int next_page;      /**< an index to the next unused page block */
+  char *alloc_block;  /**< pointer to the current allocation block */
+  size_t alloc_used;  /**< number of bytes in the current allocation block that has been used */
+} amqp_pool_t;
+
+/**
+ * An amqp method
+ *
+ * \since v0.1
+ */
+typedef struct amqp_method_t_ {
+  amqp_method_number_t id;      /**< the method id number */
+  void *decoded;                /**< pointer to the decoded method,
+                                 *    cast to the appropriate type to use */
+} amqp_method_t;
+
+/**
+ * An AMQP frame
+ *
+ * \since v0.1
+ */
+typedef struct amqp_frame_t_ {
+  uint8_t frame_type;       /**< frame type. The types:
+                             * - AMQP_FRAME_METHOD - use the method union member
+                             * - AMQP_FRAME_HEADER - use the properties union member
+                             * - AMQP_FRAME_BODY - use the body_fragment union member
+                             */
+  amqp_channel_t channel;   /**< the channel the frame was received on */
+  union {
+    amqp_method_t method;   /**< a method, use if frame_type == AMQP_FRAME_METHOD */
+    struct {
+      uint16_t class_id;    /**< the class for the properties */
+      uint64_t body_size;   /**< size of the body in bytes */
+      void *decoded;        /**< the decoded properties */
+      amqp_bytes_t raw;     /**< amqp-encoded properties structure */
+    } properties;           /**< message header, a.k.a., properties,
+                                  use if frame_type == AMQP_FRAME_HEADER */
+    amqp_bytes_t body_fragment; /**< a body fragment, use if frame_type == AMQP_FRAME_BODY */
+    struct {
+      uint8_t transport_high;           /**< @internal first byte of handshake */
+      uint8_t transport_low;            /**< @internal second byte of handshake */
+      uint8_t protocol_version_major;   /**< @internal third byte of handshake */
+      uint8_t protocol_version_minor;   /**< @internal fourth byte of handshake */
+    } protocol_header;    /**< Used only when doing the initial handshake with the broker,
+                                don't use otherwise */
+  } payload;              /**< the payload of the frame */
+} amqp_frame_t;
+
+/**
+ * Response type
+ *
+ * \since v0.1
+ */
+typedef enum amqp_response_type_enum_ {
+  AMQP_RESPONSE_NONE = 0,         /**< the library got an EOF from the socket */
+  AMQP_RESPONSE_NORMAL,           /**< response normal, the RPC completed successfully */
+  AMQP_RESPONSE_LIBRARY_EXCEPTION,/**< library error, an error occurred in the library, examine the library_error */
+  AMQP_RESPONSE_SERVER_EXCEPTION  /**< server exception, the broker returned an error, check replay */
+} amqp_response_type_enum;
+
+/**
+ * Reply from a RPC method on the broker
+ *
+ * \since v0.1
+ */
+typedef struct amqp_rpc_reply_t_ {
+  amqp_response_type_enum reply_type;   /**< the reply type:
+                                         * - AMQP_RESPONSE_NORMAL - the RPC completed successfully
+                                         * - AMQP_RESPONSE_SERVER_EXCEPTION - the broker returned
+                                         *     an exception, check the reply field
+                                         * - AMQP_RESPONSE_LIBRARY_EXCEPTION - the library
+                                         *    encountered an error, check the library_error field
+                                         */
+  amqp_method_t reply;                  /**< in case of AMQP_RESPONSE_SERVER_EXCEPTION this
+                                         * field will be set to the method returned from the broker */
+  int library_error;                    /**< in case of AMQP_RESPONSE_LIBRARY_EXCEPTION this
+                                         *    field will be set to an error code. An error
+                                         *     string can be retrieved using amqp_error_string */
+} amqp_rpc_reply_t;
+
+/**
+ * SASL method type
+ *
+ * \since v0.1
+ */
+typedef enum amqp_sasl_method_enum_ {
+  AMQP_SASL_METHOD_PLAIN = 0      /**< the PLAIN SASL method for authentication to the broker */
+} amqp_sasl_method_enum;
+
+/**
+ * connection state object
+ *
+ * \since v0.1
+ */
+typedef struct amqp_connection_state_t_ *amqp_connection_state_t;
+
+/**
+ * Socket object
+ *
+ * \since v0.4.0
+ */
+typedef struct amqp_socket_t_ amqp_socket_t;
+
+/**
+ * Status codes
+ *
+ * \since v0.4.0
+ */
+typedef enum amqp_status_enum_
+{
+  AMQP_STATUS_OK =                         0x0,     /**< Operation successful */
+  AMQP_STATUS_NO_MEMORY =                 -0x0001,  /**< Memory allocation
+                                                         failed */
+  AMQP_STATUS_BAD_AMQP_DATA =             -0x0002, /**< Incorrect or corrupt
+                                                        data was received from
+                                                        the broker. This is a
+                                                        protocol error. */
+  AMQP_STATUS_UNKNOWN_CLASS =             -0x0003, /**< An unknown AMQP class
+                                                        was received. This is
+                                                        a protocol error. */
+  AMQP_STATUS_UNKNOWN_METHOD =            -0x0004, /**< An unknown AMQP method
+                                                        was received. This is
+                                                        a protocol error. */
+  AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED= -0x0005, /**< Unable to resolve the
+                                                    * hostname */
+  AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION = -0x0006, /**< The broker advertised
+                                                        an incompaible AMQP
+                                                        version */
+  AMQP_STATUS_CONNECTION_CLOSED =         -0x0007, /**< The connection to the
+                                                        broker has been closed
+                                                        */
+  AMQP_STATUS_BAD_URL =                   -0x0008, /**< malformed AMQP URL */
+  AMQP_STATUS_SOCKET_ERROR =              -0x0009, /**< A socket error
+                                                        occurred */
+  AMQP_STATUS_INVALID_PARAMETER =         -0x000A, /**< An invalid parameter
+                                                        was passed into the
+                                                        function */
+  AMQP_STATUS_TABLE_TOO_BIG =             -0x000B, /**< The amqp_table_t object
+                                                        cannot be serialized
+                                                        because the output
+                                                        buffer is too small */
+  AMQP_STATUS_WRONG_METHOD =              -0x000C, /**< The wrong method was
+                                                        received */
+  AMQP_STATUS_TIMEOUT =                   -0x000D, /**< Operation timed out */
+  AMQP_STATUS_TIMER_FAILURE =             -0x000E, /**< The underlying system
+                                                        timer facility failed */
+  AMQP_STATUS_HEARTBEAT_TIMEOUT =         -0x000F, /**< Timed out waiting for
+                                                        heartbeat */
+  AMQP_STATUS_UNEXPECTED_STATE =          -0x0010, /**< Unexpected protocol
+                                                        state */
+
+  AMQP_STATUS_TCP_ERROR =                 -0x0100, /**< A generic TCP error
+                                                        occurred */
+  AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR =  -0x0101, /**< An error occurred trying
+                                                        to initialize the
+                                                        socket library*/
+
+  AMQP_STATUS_SSL_ERROR =                 -0x0200, /**< A generic SSL error
+                                                        occurred. */
+  AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED= -0x0201, /**< SSL validation of
+                                                        hostname against
+                                                        peer certificate
+                                                        failed */
+  AMQP_STATUS_SSL_PEER_VERIFY_FAILED =    -0x0202, /**< SSL validation of peer
+                                                        certificate failed. */
+  AMQP_STATUS_SSL_CONNECTION_FAILED =     -0x0203  /**< SSL handshake failed. */
+} amqp_status_enum;
+
+/**
+ * AMQP delivery modes.
+ * Use these values for the #amqp_basic_properties_t::delivery_mode field.
+ *
+ * \since v0.5
+ */
+typedef enum {
+	AMQP_DELIVERY_NONPERSISTENT = 1, /**< Non-persistent message */
+	AMQP_DELIVERY_PERSISTENT = 2 /**< Persistent message */
+} amqp_delivery_mode_enum;
+
+AMQP_END_DECLS
+
+#include <amqp_framing.h>
+
+AMQP_BEGIN_DECLS
+
+/**
+ * Empty bytes structure
+ *
+ * \since v0.2
+ */
+AMQP_PUBLIC_VARIABLE const amqp_bytes_t amqp_empty_bytes;
+
+/**
+ * Empty table structure
+ *
+ * \since v0.2
+ */
+AMQP_PUBLIC_VARIABLE const amqp_table_t amqp_empty_table;
+
+/**
+ * Empty table array structure
+ *
+ * \since v0.2
+ */
+AMQP_PUBLIC_VARIABLE const amqp_array_t amqp_empty_array;
+
+/* Compatibility macros for the above, to avoid the need to update
+   code written against earlier versions of librabbitmq. */
+
+/**
+ * \def AMQP_EMPTY_BYTES
+ *
+ * Deprecated, use \ref amqp_empty_bytes instead
+ *
+ * \deprecated use \ref amqp_empty_bytes instead
+ *
+ * \since v0.1
+ */
+#define AMQP_EMPTY_BYTES amqp_empty_bytes
+
+/**
+ * \def AMQP_EMPTY_TABLE
+ *
+ * Deprecated, use \ref amqp_empty_table instead
+ *
+ * \deprecated use \ref amqp_empty_table instead
+ *
+ * \since v0.1
+ */
+#define AMQP_EMPTY_TABLE amqp_empty_table
+
+/**
+ * \def AMQP_EMPTY_ARRAY
+ *
+ * Deprecated, use \ref amqp_empty_array instead
+ *
+ * \deprecated use \ref amqp_empty_array instead
+ *
+ * \since v0.1
+ */
+#define AMQP_EMPTY_ARRAY amqp_empty_array
+
+/**
+ * Initializes an amqp_pool_t memory allocation pool for use
+ *
+ * Readies an allocation pool for use. An amqp_pool_t
+ * must be initialized before use
+ *
+ * \param [in] pool the amqp_pool_t structure to initialize.
+ *              Calling this function on a pool a pool that has
+ *              already been initialized will result in undefined
+ *              behavior
+ * \param [in] pagesize the unit size that the pool will allocate
+ *              memory chunks in. Anything allocated against the pool
+ *              with a requested size will be carved out of a block
+ *              this size. Allocations larger than this will be
+ *              allocated individually
+ *
+ * \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(),
+ *     amqp_pool_alloc_bytes(), amqp_pool_t
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL init_amqp_pool(amqp_pool_t *pool, size_t pagesize);
+
+/**
+ * Recycles an amqp_pool_t memory allocation pool
+ *
+ * Recycles the space allocate by the pool
+ *
+ * This invalidates all allocations made against the pool before this call is
+ * made, any use of any allocations made before recycle_amqp_pool() is called
+ * will result in undefined behavior.
+ *
+ * Note: this may or may not release memory, to force memory to be released
+ * call empty_amqp_pool().
+ *
+ * \param [in] pool the amqp_pool_t to recycle
+ *
+ * \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(),
+ *      amqp_pool_alloc_bytes()
+ *
+ * \since v0.1
+ *
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL recycle_amqp_pool(amqp_pool_t *pool);
+
+/**
+ * Empties an amqp memory pool
+ *
+ * Releases all memory associated with an allocation pool
+ *
+ * \param [in] pool the amqp_pool_t to empty
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL empty_amqp_pool(amqp_pool_t *pool);
+
+/**
+ * Allocates a block of memory from an amqp_pool_t memory pool
+ *
+ * Memory will be aligned on a 8-byte boundary. If a 0-length allocation is
+ * requested, a NULL pointer will be returned.
+ *
+ * \param [in] pool the allocation pool to allocate the memory from
+ * \param [in] amount the size of the allocation in bytes.
+ * \return a pointer to the memory block, or NULL if the allocation cannot
+ *          be satisfied.
+ *
+ * \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(),
+ *     amqp_pool_alloc_bytes()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void *
+AMQP_CALL amqp_pool_alloc(amqp_pool_t *pool, size_t amount);
+
+/**
+ * Allocates a block of memory from an amqp_pool_t to an amqp_bytes_t
+ *
+ * Memory will be aligned on a 8-byte boundary. If a 0-length allocation is
+ * requested, output.bytes = NULL.
+ *
+ * \param [in] pool the allocation pool to allocate the memory from
+ * \param [in] amount the size of the allocation in bytes
+ * \param [in] output the location to store the pointer. On success
+ *              output.bytes will be set to the beginning of the buffer
+ *              output.len will be set to amount
+ *              On error output.bytes will be set to NULL and output.len
+ *              set to 0
+ *
+ * \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(),
+ *     amqp_pool_alloc()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, amqp_bytes_t *output);
+
+/**
+ * Wraps a c string in an amqp_bytes_t
+ *
+ * Takes a string, calculates its length and creates an
+ * amqp_bytes_t that points to it. The string is not duplicated.
+ *
+ * For a given input cstr, The amqp_bytes_t output.bytes is the
+ * same as cstr, output.len is the length of the string not including
+ * the \0 terminator
+ *
+ * This function uses strlen() internally so cstr must be properly
+ * terminated
+ *
+ * \param [in] cstr the c string to wrap
+ * \return an amqp_bytes_t that describes the string
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_bytes_t
+AMQP_CALL amqp_cstring_bytes(char const *cstr);
+
+/**
+ * Duplicates an amqp_bytes_t buffer.
+ *
+ * The buffer is cloned and the contents copied.
+ *
+ * The memory associated with the output is allocated
+ * with amqp_bytes_malloc() and should be freed with
+ * amqp_bytes_free()
+ *
+ * \param [in] src
+ * \return a clone of the src
+ *
+ * \sa amqp_bytes_free(), amqp_bytes_malloc()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_bytes_t
+AMQP_CALL amqp_bytes_malloc_dup(amqp_bytes_t src);
+
+/**
+ * Allocates a amqp_bytes_t buffer
+ *
+ * Creates an amqp_bytes_t buffer of the specified amount, the buffer should be
+ * freed using amqp_bytes_free()
+ *
+ * \param [in] amount the size of the buffer in bytes
+ * \returns an amqp_bytes_t with amount bytes allocated.
+ *           output.bytes will be set to NULL on error
+ *
+ * \sa amqp_bytes_free(), amqp_bytes_malloc_dup()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_bytes_t
+AMQP_CALL amqp_bytes_malloc(size_t amount);
+
+/**
+ * Frees an amqp_bytes_t buffer
+ *
+ * Frees a buffer allocated with amqp_bytes_malloc() or amqp_bytes_malloc_dup()
+ *
+ * Calling amqp_bytes_free on buffers not allocated with one
+ * of those two functions will result in undefined behavior
+ *
+ * \param [in] bytes the buffer to free
+ *
+ * \sa amqp_bytes_malloc(), amqp_bytes_malloc_dup()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_bytes_free(amqp_bytes_t bytes);
+
+/**
+ * Allocate and initialize a new amqp_connection_state_t object
+ *
+ * amqp_connection_state_t objects created with this function
+ * should be freed with amqp_destroy_connection()
+ *
+ * \returns an opaque pointer on success, NULL or 0 on failure.
+ *
+ * \sa amqp_destroy_connection()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_connection_state_t
+AMQP_CALL amqp_new_connection(void);
+
+/**
+ * Get the underlying socket descriptor for the connection
+ *
+ * \warning Use the socket returned from this function carefully, incorrect use
+ * of the socket outside of the library will lead to undefined behavior.
+ * Additionally rabbitmq-c may use the socket differently version-to-version,
+ * what may work in one version, may break in the next version. Be sure to
+ * throughly test any applications that use the socket returned by this
+ * function especially when using a newer version of rabbitmq-c
+ *
+ * \param [in] state the connection object
+ * \returns the socket descriptor if one has been set, -1 otherwise
+ *
+ * \sa amqp_tcp_socket_new(), amqp_ssl_socket_new(), amqp_socket_open()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_get_sockfd(amqp_connection_state_t state);
+
+
+/**
+ * Deprecated, use amqp_tcp_socket_new() or amqp_ssl_socket_new()
+ *
+ * \deprecated Use amqp_tcp_socket_new() or amqp_ssl_socket_new()
+ *
+ * Sets the socket descriptor associated with the connection. The socket
+ * should be connected to a broker, and should not be read to or written from
+ * before calling this function.  A socket descriptor can be created and opened
+ * using amqp_open_socket()
+ *
+ * \param [in] state the connection object
+ * \param [in] sockfd the socket
+ *
+ * \sa amqp_open_socket(), amqp_tcp_socket_new(), amqp_ssl_socket_new()
+ *
+ * \since v0.1
+ */
+AMQP_DEPRECATED(
+  AMQP_PUBLIC_FUNCTION
+  void
+  AMQP_CALL amqp_set_sockfd(amqp_connection_state_t state, int sockfd)
+);
+
+
+/**
+ * Tune client side parameters
+ *
+ * \warning This function may call abort() if the connection is in a certain
+ *  state. As such it should probably not be called code outside the library.
+ *  connection parameters should be specified when calling amqp_login() or
+ *  amqp_login_with_properties()
+ *
+ * This function changes channel_max, frame_max, and heartbeat parameters, on
+ * the client side only. It does not try to renegotiate these parameters with
+ * the broker. Using this function will lead to unexpected results.
+ *
+ * \param [in] state the connection object
+ * \param [in] channel_max the maximum number of channels.
+ *              The largest this can be is 65535
+ * \param [in] frame_max the maximum size of an frame.
+ *              The smallest this can be is 4096
+ *              The largest this can be is 2147483647
+ *              Unless you know what you're doing the recommended
+ *              size is 131072 or 128KB
+ * \param [in] heartbeat the number of seconds between heartbeats
+ *
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise.
+ *  Possible error codes include:
+ *  - AMQP_STATUS_NO_MEMORY memory allocation failed.
+ *  - AMQP_STATUS_TIMER_FAILURE the underlying system timer indicated it
+ *    failed.
+ *
+ * \sa amqp_login(), amqp_login_with_properties()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_tune_connection(amqp_connection_state_t state,
+                               int channel_max,
+                               int frame_max,
+                               int heartbeat);
+
+/**
+ * Get the maximum number of channels the connection can handle
+ *
+ * The maximum number of channels is set when connection negotiation takes
+ * place in amqp_login() or amqp_login_with_properties().
+ *
+ * \param [in] state the connection object
+ * \return the maximum number of channels. 0 if there is no limit
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_get_channel_max(amqp_connection_state_t state);
+
+/**
+ * Destroys an amqp_connection_state_t object
+ *
+ * Destroys a amqp_connection_state_t object that was created with
+ * amqp_new_connection(). If the connection with the broker is open, it will be
+ * implicitly closed with a reply code of 200 (success). Any memory that
+ * would be freed with amqp_maybe_release_buffers() or
+ * amqp_maybe_release_buffers_on_channel() will be freed, and use of that
+ * memory will caused undefined behavior.
+ *
+ * \param [in] state the connection object
+ * \return AMQP_STATUS_OK on success. amqp_status_enum value failure
+ *
+ * \sa amqp_new_connection()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_destroy_connection(amqp_connection_state_t state);
+
+/**
+ * Process incoming data
+ *
+ * \warning This is a low-level function intended for those who want to
+ *  have greater control over input and output over the socket from the
+ *  broker. Correctly using this function requires in-depth knowledge of AMQP
+ *  and rabbitmq-c.
+ *
+ * For a given buffer of data received from the broker, decode the first
+ * frame in the buffer. If more than one frame is contained in the input buffer
+ * the return value will be less than the received_data size, the caller should
+ * adjust received_data buffer descriptor to point to the beginning of the
+ * buffer + the return value.
+ *
+ * \param [in] state the connection object
+ * \param [in] received_data a buffer of data received from the broker. The
+ *  function will return the number of bytes of the buffer it used. The
+ *  function copies these bytes to an internal buffer: this part of the buffer
+ *  may be reused after this function successfully completes.
+ * \param [in,out] decoded_frame caller should pass in a pointer to an
+ *  amqp_frame_t struct. If there is enough data in received_data for a
+ *  complete frame, decoded_frame->frame_type will be set to something OTHER
+ *  than 0. decoded_frame may contain members pointing to memory owned by
+ *  the state object. This memory can be recycled with amqp_maybe_release_buffers()
+ *  or amqp_maybe_release_buffers_on_channel()
+ * \return number of bytes consumed from received_data or 0 if a 0-length
+ *  buffer was passed. A negative return value indicates failure. Possible errors:
+ *  - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
+ *    an indeterminate state making recovery unlikely. Client should note the error
+ *    and terminate the application
+ *  - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
+ *    should be shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
+ *    broker. This is likely a protocol error and the connection should be
+ *    shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
+ *    was received from the broker. This is likely a protocol error and the
+ *    connection should be shutdown immediately
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_handle_input(amqp_connection_state_t state,
+                            amqp_bytes_t received_data,
+                            amqp_frame_t *decoded_frame);
+
+/**
+ * Check to see if connection memory can be released
+ *
+ * \deprecated This function is deprecated in favor of
+ *  amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel()
+ *
+ * Checks the state of an amqp_connection_state_t object to see if
+ * amqp_release_buffers() can be called successfully.
+ *
+ * \param [in] state the connection object
+ * \returns TRUE if the buffers can be released FALSE otherwise
+ *
+ * \sa amqp_release_buffers() amqp_maybe_release_buffers()
+ *  amqp_maybe_release_buffers_on_channel()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_boolean_t
+AMQP_CALL amqp_release_buffers_ok(amqp_connection_state_t state);
+
+/**
+ * Release amqp_connection_state_t owned memory
+ *
+ * \deprecated This function is deprecated in favor of
+ *  amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel()
+ *
+ * \warning caller should ensure amqp_release_buffers_ok() returns true before
+ *  calling this function. Failure to do so may result in abort() being called.
+ *
+ * Release memory owned by the amqp_connection_state_t for reuse by the
+ * library. Use of any memory returned by the library before this function is
+ * called will result in undefined behavior.
+ *
+ * \note internally rabbitmq-c tries to reuse memory when possible. As a result
+ * its possible calling this function may not have a noticeable effect on
+ * memory usage.
+ *
+ * \param [in] state the connection object
+ *
+ * \sa amqp_release_buffers_ok() amqp_maybe_release_buffers()
+ *  amqp_maybe_release_buffers_on_channel()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_release_buffers(amqp_connection_state_t state);
+
+/**
+ * Release amqp_connection_state_t owned memory
+ *
+ * Release memory owned by the amqp_connection_state_t object related to any
+ * channel, allowing reuse by the library. Use of any memory returned by the
+ * library before this function is called with result in undefined behavior.
+ *
+ * \note internally rabbitmq-c tries to reuse memory when possible. As a result
+ * its possible calling this function may not have a noticeable effect on
+ * memory usage.
+ *
+ * \param [in] state the connection object
+ *
+ * \sa amqp_maybe_release_buffers_on_channel()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_maybe_release_buffers(amqp_connection_state_t state);
+
+/**
+ * Release amqp_connection_state_t owned memory related to a channel
+ *
+ * Release memory owned by the amqp_connection_state_t object related to the
+ * specified channel, allowing reuse by the library. Use of any memory returned
+ * the library for a specific channel will result in undefined behavior.
+ *
+ * \note internally rabbitmq-c tries to reuse memory when possible. As a result
+ * its possible calling this function may not have a noticeable effect on
+ * memory usage.
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel specifier for which memory should be
+ *  released. Note that the library does not care about the state of the
+ *  channel when calling this function
+ *
+ * \sa amqp_maybe_release_buffers()
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_maybe_release_buffers_on_channel(amqp_connection_state_t state,
+                                                amqp_channel_t channel);
+
+/**
+ * Send a frame to the broker
+ *
+ * \param [in] state the connection object
+ * \param [in] frame the frame to send to the broker
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum value on error.
+ *  Possible error codes:
+ *  - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or
+ *    properties was too large to fit in a single AMQP frame, or the
+ *    method contains an invalid value. The frame was not sent.
+ *  - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is
+ *    too large to fit in a single AMQP frame. Frame was not sent.
+ *  - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in
+ *  - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in
+ *  - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame
+ *    was sent
+ *  - AMQP_STATUS_SOCKET_ERROR
+ *  - AMQP_STATUS_SSL_ERROR
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_send_frame(amqp_connection_state_t state, amqp_frame_t const *frame);
+
+/**
+ * Compare two table entries
+ *
+ * Works just like strcmp(), comparing two the table keys, datatype, then values
+ *
+ * \param [in] entry1 the entry on the left
+ * \param [in] entry2 the entry on the right
+ * \return 0 if entries are equal, 0 < if left is greater, 0 > if right is greater
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_table_entry_cmp(void const *entry1, void const *entry2);
+
+/**
+ * Open a socket to a remote host
+ *
+ * \deprecated This function is deprecated in favor of amqp_socket_open()
+ *
+ * Looks up the hostname, then attempts to open a socket to the host using
+ * the specified portnumber. It also sets various options on the socket to
+ * improve performance and correctness.
+ *
+ * \param [in] hostname this can be a hostname or IP address.
+ *              Both IPv4 and IPv6 are acceptable
+ * \param [in] portnumber the port to connect on. RabbitMQ brokers
+ *              listen on port 5672, and 5671 for SSL
+ * \return a positive value indicates success and is the sockfd. A negative
+ *  value (see amqp_status_enum)is returned on failure. Possible error codes:
+ *  - AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR Initialization of underlying socket
+ *    library failed.
+ *  - AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED hostname lookup failed.
+ *  - AMQP_STATUS_SOCKET_ERROR a socket error occurred. errno or WSAGetLastError()
+ *    may return more useful information.
+ *
+ * \note IPv6 support was added in v0.3
+ *
+ * \sa amqp_socket_open() amqp_set_sockfd()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_open_socket(char const *hostname, int portnumber);
+
+/**
+ * Send initial AMQP header to the broker
+ *
+ * \warning this is a low level function intended for those who want to
+ * interact with the broker at a very low level. Use of this function without
+ * understanding what it does will result in AMQP protocol errors.
+ *
+ * This function sends the AMQP protocol header to the broker.
+ *
+ * \param [in] state the connection object
+ * \return AMQP_STATUS_OK on success, a negative value on failure. Possible
+ *  error codes:
+ * - AMQP_STATUS_CONNECTION_CLOSED the connection to the broker was closed.
+ * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. It is likely the
+ *   underlying socket has been closed. errno or WSAGetLastError() may provide
+ *   further information.
+ * - AMQP_STATUS_SSL_ERROR a SSL error occurred. The connection to the broker
+ *   was closed.
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_send_header(amqp_connection_state_t state);
+
+/**
+ * Checks to see if there are any incoming frames ready to be read
+ *
+ * Checks to see if there are any amqp_frame_t objects buffered by the
+ * amqp_connection_state_t object. Having one or more frames buffered means
+ * that amqp_simple_wait_frame() or amqp_simple_wait_frame_noblock() will
+ * return a frame without potentially blocking on a read() call.
+ *
+ * \param [in] state the connection object
+ * \return TRUE if there are frames enqueued, FALSE otherwise
+ *
+ * \sa amqp_simple_wait_frame() amqp_simple_wait_frame_noblock()
+ *  amqp_data_in_buffer()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_boolean_t
+AMQP_CALL amqp_frames_enqueued(amqp_connection_state_t state);
+
+/**
+ * Read a single amqp_frame_t
+ *
+ * Waits for the next amqp_frame_t frame to be read from the broker.
+ * This function has the potential to block for a long time in the case of
+ * waiting for a basic.deliver method frame from the broker.
+ *
+ * The library may buffer frames. When an amqp_connection_state_t object
+ * has frames buffered calling amqp_simple_wait_frame() will return an
+ * amqp_frame_t without entering a blocking read(). You can test to see if
+ * an amqp_connection_state_t object has frames buffered by calling the
+ * amqp_frames_enqueued() function.
+ *
+ * The library has a socket read buffer. When there is data in an
+ * amqp_connection_state_t read buffer, amqp_simple_wait_frame() may return an
+ * amqp_frame_t without entering a blocking read(). You can test to see if an
+ * amqp_connection_state_t object has data in its read buffer by calling the
+ * amqp_data_in_buffer() function.
+ *
+ * \param [in] state the connection object
+ * \param [out] decoded_frame the frame
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum value
+ *  is returned otherwise. Possible errors include:
+ *  - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
+ *    an indeterminate state making recovery unlikely. Client should note the error
+ *    and terminate the application
+ *  - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
+ *    should be shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
+ *    broker. This is likely a protocol error and the connection should be
+ *    shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
+ *    was received from the broker. This is likely a protocol error and the
+ *    connection should be shutdown immediately
+ *  - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat
+ *    from the broker. The connection has been closed.
+ *  - AMQP_STATUS_TIMER_FAILURE system timer indicated failure.
+ *  - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has
+ *    been closed
+ *  - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has
+ *    been closed.
+ *
+ * \sa amqp_simple_wait_frame_noblock() amqp_frames_enqueued()
+ *  amqp_data_in_buffer()
+ *
+ * \note as of v0.4.0 this function will no longer return heartbeat frames
+ *  when enabled by specifying a non-zero heartbeat value in amqp_login().
+ *  Heartbeating is handled internally by the library.
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_simple_wait_frame(amqp_connection_state_t state,
+                                 amqp_frame_t *decoded_frame);
+
+/**
+ * Read a single amqp_frame_t with a timeout.
+ *
+ * Waits for the next amqp_frame_t frame to be read from the broker, up to
+ * a timespan specified by tv. The function will return AMQP_STATUS_TIMEOUT
+ * if the timeout is reached. The tv value is not modified by the function.
+ *
+ * If a 0 timeval is specified, the function behaves as if its non-blocking: it
+ * will test to see if a frame can be read from the broker, and return immediately.
+ *
+ * If NULL is passed in for tv, the function will behave like
+ * amqp_simple_wait_frame() and block until a frame is received from the broker
+ *
+ * The library may buffer frames.  When an amqp_connection_state_t object
+ * has frames buffered calling amqp_simple_wait_frame_noblock() will return an
+ * amqp_frame_t without entering a blocking read(). You can test to see if an
+ * amqp_connection_state_t object has frames buffered by calling the
+ * amqp_frames_enqueued() function.
+ *
+ * The library has a socket read buffer. When there is data in an
+ * amqp_connection_state_t read buffer, amqp_simple_wait_frame_noblock() may return
+ * an amqp_frame_t without entering a blocking read(). You can test to see if an
+ * amqp_connection_state_t object has data in its read buffer by calling the
+ * amqp_data_in_buffer() function.
+ *
+ * \note This function does not return heartbeat frames. When enabled, heartbeating
+ *  is handed internally internally by the library
+ *
+ * \param [in,out] state the connection object
+ * \param [out] decoded_frame the frame
+ * \param [in] tv the maximum time to wait for a frame to be read. Setting
+ * tv->tv_sec = 0 and tv->tv_usec = 0 will do a non-blocking read. Specifying
+ * NULL for tv will make the function block until a frame is read.
+ * \return AMQP_STATUS_OK on success. An amqp_status_enum value is returned
+ *  otherwise. Possible errors include:
+ *  - AMQP_STATUS_TIMEOUT the timeout was reached while waiting for a frame
+ *    from the broker.
+ *  - AMQP_STATUS_INVALID_PARAMETER the tv parameter contains an invalid value.
+ *  - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
+ *    an indeterminate state making recovery unlikely. Client should note the error
+ *    and terminate the application
+ *  - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
+ *    should be shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
+ *    broker. This is likely a protocol error and the connection should be
+ *    shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
+ *    was received from the broker. This is likely a protocol error and the
+ *    connection should be shutdown immediately
+ *  - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat
+ *    from the broker. The connection has been closed.
+ *  - AMQP_STATUS_TIMER_FAILURE system timer indicated failure.
+ *  - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has
+ *    been closed
+ *  - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has
+ *    been closed.
+ *
+ * \sa amqp_simple_wait_frame() amqp_frames_enqueued() amqp_data_in_buffer()
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_simple_wait_frame_noblock(amqp_connection_state_t state,
+                                         amqp_frame_t *decoded_frame,
+                                         struct timeval *tv);
+
+/**
+ * Waits for a specific method from the broker
+ *
+ * \warning You probably don't want to use this function. If this function
+ *  doesn't receive exactly the frame requested it closes the whole connection.
+ *
+ * Waits for a single method on a channel from the broker.
+ * If a frame is received that does not match expected_channel
+ * or expected_method the program will abort
+ *
+ * \param [in] state the connection object
+ * \param [in] expected_channel the channel that the method should be delivered on
+ * \param [in] expected_method the method to wait for
+ * \param [out] output the method
+ * \returns AMQP_STATUS_OK on success. An amqp_status_enum value is returned
+ *  otherwise. Possible errors include:
+ *  - AMQP_STATUS_WRONG_METHOD a frame containing the wrong method, wrong frame
+ *    type or wrong channel was received. The connection is closed.
+ *  - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely in
+ *    an indeterminate state making recovery unlikely. Client should note the error
+ *    and terminate the application
+ *  - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection
+ *    should be shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the
+ *    broker. This is likely a protocol error and the connection should be
+ *    shutdown immediately
+ *  - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class
+ *    was received from the broker. This is likely a protocol error and the
+ *    connection should be shutdown immediately
+ *  - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat
+ *    from the broker. The connection has been closed.
+ *  - AMQP_STATUS_TIMER_FAILURE system timer indicated failure.
+ *  - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has
+ *    been closed
+ *  - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has
+ *    been closed.
+ *
+ * \since v0.1
+ */
+
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_simple_wait_method(amqp_connection_state_t state,
+                                  amqp_channel_t expected_channel,
+                                  amqp_method_number_t expected_method,
+                                  amqp_method_t *output);
+
+/**
+ * Sends a method to the broker
+ *
+ * This is a thin wrapper around amqp_send_frame(), providing a way to send
+ * a method to the broker on a specified channel.
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel object
+ * \param [in] id the method number
+ * \param [in] decoded the method object
+ * \returns AMQP_STATUS_OK on success, an amqp_status_enum value otherwise.
+ *  Possible errors include:
+ *  - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or
+ *    properties was too large to fit in a single AMQP frame, or the
+ *    method contains an invalid value. The frame was not sent.
+ *  - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is
+ *    too large to fit in a single AMQP frame. Frame was not sent.
+ *  - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in
+ *  - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in
+ *  - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame
+ *    was sent
+ *  - AMQP_STATUS_SOCKET_ERROR
+ *  - AMQP_STATUS_SSL_ERROR
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_send_method(amqp_connection_state_t state,
+                           amqp_channel_t channel,
+                           amqp_method_number_t id,
+                           void *decoded);
+
+/**
+ * Sends a method to the broker and waits for a method response
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel object
+ * \param [in] request_id the method number of the request
+ * \param [in] expected_reply_ids a 0 terminated array of expected response
+ *             method numbers
+ * \param [in] decoded_request_method the method to be sent to the broker
+ * \return a amqp_rpc_reply_t:
+ *  - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully
+ *  - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
+ *    exception:
+ *    - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
+ *      occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
+ *      of the exception. The client should amqp_send_method() a
+ *      amqp_channel_close_ok_t. The channel must be re-opened before it
+ *      can be used again. Any resources associated with the channel
+ *      (auto-delete exchanges, auto-delete queues, consumers) are invalid
+ *      and must be recreated before attempting to use them again.
+ *    - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
+ *      occurred, cast r.reply.decoded to amqp_connection_close_t* to see
+ *      details of the exception. The client amqp_send_method() a
+ *      amqp_connection_close_ok_t and disconnect from the broker.
+ *  - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred
+ *    within the library. Examine r.library_error and compare it against
+ *    amqp_status_enum values to determine the error.
+ *
+ * \sa amqp_simple_rpc_decoded()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_simple_rpc(amqp_connection_state_t state,
+                          amqp_channel_t channel,
+                          amqp_method_number_t request_id,
+                          amqp_method_number_t *expected_reply_ids,
+                          void *decoded_request_method);
+
+/**
+ * Sends a method to the broker and waits for a method response
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel object
+ * \param [in] request_id the method number of the request
+ * \param [in] reply_id the method number expected in response
+ * \param [in] decoded_request_method the request method
+ * \return a pointer to the method returned from the broker, or NULL on error.
+ *  On error amqp_get_rpc_reply() will return an amqp_rpc_reply_t with
+ *  details on the error that occurred.
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+void *
+AMQP_CALL amqp_simple_rpc_decoded(amqp_connection_state_t state,
+                                  amqp_channel_t channel,
+                                  amqp_method_number_t request_id,
+                                  amqp_method_number_t reply_id,
+                                  void *decoded_request_method);
+
+/**
+ * Get the last global amqp_rpc_reply
+ *
+ * The API methods corresponding to most synchronous AMQP methods
+ * return a pointer to the decoded method result.  Upon error, they
+ * return NULL, and we need some way of discovering what, if anything,
+ * went wrong. amqp_get_rpc_reply() returns the most recent
+ * amqp_rpc_reply_t instance corresponding to such an API operation
+ * for the given connection.
+ *
+ * Only use it for operations that do not themselves return
+ * amqp_rpc_reply_t; operations that do return amqp_rpc_reply_t
+ * generally do NOT update this per-connection-global amqp_rpc_reply_t
+ * instance.
+ *
+ * \param [in] state the connection object
+ * \return the most recent amqp_rpc_reply_t:
+ *  - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully
+ *  - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
+ *    exception:
+ *    - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
+ *      occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
+ *      of the exception. The client should amqp_send_method() a
+ *      amqp_channel_close_ok_t. The channel must be re-opened before it
+ *      can be used again. Any resources associated with the channel
+ *      (auto-delete exchanges, auto-delete queues, consumers) are invalid
+ *      and must be recreated before attempting to use them again.
+ *    - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
+ *      occurred, cast r.reply.decoded to amqp_connection_close_t* to see
+ *      details of the exception. The client amqp_send_method() a
+ *      amqp_connection_close_ok_t and disconnect from the broker.
+ *  - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred
+ *    within the library. Examine r.library_error and compare it against
+ *    amqp_status_enum values to determine the error.
+ *
+ * \sa amqp_simple_rpc_decoded()
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_get_rpc_reply(amqp_connection_state_t state);
+
+/**
+ * Login to the broker
+ *
+ * After using amqp_open_socket and amqp_set_sockfd, call
+ * amqp_login to complete connecting to the broker
+ *
+ * \param [in] state the connection object
+ * \param [in] vhost the virtual host to connect to on the broker. The default
+ *              on most brokers is "/"
+ * \param [in] channel_max the limit for number of channels for the connection.
+ *              0 means no limit, and is a good default (AMQP_DEFAULT_MAX_CHANNELS)
+ *              Note that the maximum number of channels the protocol supports
+ *              is 65535 (2^16, with the 0-channel reserved)
+ * \param [in] frame_max the maximum size of an AMQP frame on the wire to
+ *              request of the broker for this connection. 4096 is the minimum
+ *              size, 2^31-1 is the maximum, a good default is 131072 (128KB), or
+ *              AMQP_DEFAULT_FRAME_SIZE
+ * \param [in] heartbeat the number of seconds between heartbeat frames to
+ *              request of the broker. A value of 0 disables heartbeats.
+ *              Note rabbitmq-c only has partial support for heartbeats, as of
+ *              v0.4.0 they are only serviced during amqp_basic_publish() and
+ *              amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock()
+ * \param [in] sasl_method the SASL method to authenticate with the broker.
+ *              followed by the authentication information.
+ *              For AMQP_SASL_METHOD_PLAIN, the AMQP_SASL_METHOD_PLAIN
+ *              should be followed by two arguments in this order:
+ *              const char* username, and const char* password.
+ * \return amqp_rpc_reply_t indicating success or failure.
+ *  - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully
+ *  - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors
+ *    from the broker when logging in will be represented by the broker closing
+ *    the socket. In this case r.library_error will be set to
+ *    AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of
+ *    error conditions including: invalid vhost, authentication failure.
+ *  - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
+ *    exception:
+ *    - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
+ *      occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
+ *      of the exception. The client should amqp_send_method() a
+ *      amqp_channel_close_ok_t. The channel must be re-opened before it
+ *      can be used again. Any resources associated with the channel
+ *      (auto-delete exchanges, auto-delete queues, consumers) are invalid
+ *      and must be recreated before attempting to use them again.
+ *    - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
+ *      occurred, cast r.reply.decoded to amqp_connection_close_t* to see
+ *      details of the exception. The client amqp_send_method() a
+ *      amqp_connection_close_ok_t and disconnect from the broker.
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_login(amqp_connection_state_t state, char const *vhost,
+                     int channel_max, int frame_max, int heartbeat,
+                     amqp_sasl_method_enum sasl_method, ...);
+
+/**
+ * Login to the broker passing a properties table
+ *
+ * This function is similar to amqp_login() and differs in that it provides a
+ * way to pass client properties to the broker. This is commonly used to
+ * negotiate newer protocol features as they are supported by the broker.
+ *
+ * \param [in] state the connection object
+ * \param [in] vhost the virtual host to connect to on the broker. The default
+ *              on most brokers is "/"
+ * \param [in] channel_max the limit for the number of channels for the connection.
+ *             0 means no limit, and is a good default (AMQP_DEFAULT_MAX_CHANNELS)
+ *             Note that the maximum number of channels the protocol supports
+ *             is 65535 (2^16, with the 0-channel reserved)
+ * \param [in] frame_max the maximum size of an AMQP frame ont he wire to
+ *              request of the broker for this connection. 4096 is the minimum
+ *              size, 2^31-1 is the maximum, a good default is 131072 (128KB), or
+ *              AMQP_DEFAULT_FRAME_SIZE
+ * \param [in] heartbeat the number of seconds between heartbeat frame to
+ *             request of the broker. A value of 0 disables heartbeats.
+ *             Note rabbitmq-c only has partial support for hearts, as of
+ *             v0.4.0 heartbeats are only serviced during amqp_basic_publish(),
+ *             and amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock()
+ * \param [in] properties a table of properties to send the broker.
+ * \param [in] sasl_method the SASL method to authenticate with the broker
+ *             followed by the authentication information.
+ *             For AMQP_SASL_METHOD_PLAN, the AMQP_SASL_METHOD_PLAIN parameter
+ *             should be followed by two arguments in this order:
+ *             const char* username, and const char* password.
+ * \return amqp_rpc_reply_t indicating success or failure.
+ *  - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully
+ *  - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors
+ *    from the broker when logging in will be represented by the broker closing
+ *    the socket. In this case r.library_error will be set to
+ *    AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of
+ *    error conditions including: invalid vhost, authentication failure.
+ *  - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an
+ *    exception:
+ *    - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception
+ *      occurred, cast r.reply.decoded to amqp_channel_close_t* to see details
+ *      of the exception. The client should amqp_send_method() a
+ *      amqp_channel_close_ok_t. The channel must be re-opened before it
+ *      can be used again. Any resources associated with the channel
+ *      (auto-delete exchanges, auto-delete queues, consumers) are invalid
+ *      and must be recreated before attempting to use them again.
+ *    - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception
+ *      occurred, cast r.reply.decoded to amqp_connection_close_t* to see
+ *      details of the exception. The client amqp_send_method() a
+ *      amqp_connection_close_ok_t and disconnect from the broker.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_login_with_properties(amqp_connection_state_t state, char const *vhost,
+                                     int channel_max, int frame_max, int heartbeat,
+                                     const amqp_table_t *properties, amqp_sasl_method_enum sasl_method, ...);
+
+struct amqp_basic_properties_t_;
+
+/**
+ * Publish a message to the broker
+ *
+ * Publish a message on an exchange with a routing key.
+ *
+ * Note that at the AMQ protocol level basic.publish is an async method:
+ * this means error conditions that occur on the broker (such as publishing to
+ * a non-existent exchange) will not be reflected in the return value of this
+ * function.
+ *
+ * in the return value from this function.
+ * \param [in] state the connection object
+ * \param [in] channel the channel identifier
+ * \param [in] exchange the exchange on the broker to publish to
+ * \param [in] routing_key the routing key to use when publishing the message
+ * \param [in] mandatory indicate to the broker that the message MUST be routed
+ *              to a queue. If the broker cannot do this it should respond with
+ *              a basic.reject method.
+ * \param [in] immediate indicate to the broker that the message MUST be delivered
+ *              to a consumer immediately. If the broker cannot do this it should
+ *              response with a basic.reject method.
+ * \param [in] properties the properties associated with the message
+ * \param [in] body the message body
+ * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. Note
+ *         that basic.publish is an async method, the return value from this
+ *         function only indicates that the message data was successfully
+ *         transmitted to the broker. It does not indicate failures that occur
+ *         on the broker, such as publishing to a non-existent exchange.
+ *         Possible error values:
+ *         - AMQP_STATUS_TIMER_FAILURE: system timer facility returned an error
+ *           the message was not sent.
+ *         - AMQP_STATUS_HEARTBEAT_TIMEOUT: connection timed out waiting for a
+ *           heartbeat from the broker. The message was not sent.
+ *         - AMQP_STATUS_NO_MEMORY: memory allocation failed. The message was
+ *           not sent.
+ *         - AMQP_STATUS_TABLE_TOO_BIG: a table in the properties was too large
+ *           to fit in a single frame. Message was not sent.
+ *         - AMQP_STATUS_CONNECTION_CLOSED: the connection was closed.
+ *         - AMQP_STATUS_SSL_ERROR: a SSL error occurred.
+ *         - AMQP_STATUS_TCP_ERROR: a TCP error occurred. errno or
+ *           WSAGetLastError() may provide more information
+ *
+ * Note: this function does heartbeat processing as of v0.4.0
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_basic_publish(amqp_connection_state_t state, amqp_channel_t channel,
+                             amqp_bytes_t exchange, amqp_bytes_t routing_key,
+                             amqp_boolean_t mandatory, amqp_boolean_t immediate,
+                             struct amqp_basic_properties_t_ const *properties,
+                             amqp_bytes_t body);
+
+/**
+ * Closes an channel
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel identifier
+ * \param [in] code the reason for closing the channel, AMQP_REPLY_SUCCESS is a good default
+ * \return amqp_rpc_reply_t indicating success or failure
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_channel_close(amqp_connection_state_t state, amqp_channel_t channel,
+                             int code);
+
+/**
+ * Closes the entire connection
+ *
+ * Implicitly closes all channels and informs the broker the connection
+ * is being closed, after receiving acknowldgement from the broker it closes
+ * the socket.
+ *
+ * \param [in] state the connection object
+ * \param [in] code the reason code for closing the connection. AMQP_REPLY_SUCCESS is a good default.
+ * \return amqp_rpc_reply_t indicating the result
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_connection_close(amqp_connection_state_t state, int code);
+
+/**
+ * Acknowledges a message
+ *
+ * Does a basic.ack on a received message
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel identifier
+ * \param [in] delivery_tag the delivery tag of the message to be ack'd
+ * \param [in] multiple if true, ack all messages up to this delivery tag, if
+ *              false ack only this delivery tag
+ * \return 0 on success,  0 > on failing to send the ack to the broker.
+ *            this will not indicate failure if something goes wrong on the broker
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_basic_ack(amqp_connection_state_t state, amqp_channel_t channel,
+                         uint64_t delivery_tag, amqp_boolean_t multiple);
+
+/**
+ * Do a basic.get
+ *
+ * Synchonously polls the broker for a message in a queue, and
+ * retrieves the message if a message is in the queue.
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel identifier to use
+ * \param [in] queue the queue name to retrieve from
+ * \param [in] no_ack if true the message is automatically ack'ed
+ *              if false amqp_basic_ack should be called once the message
+ *              retrieved has been processed
+ * \return amqp_rpc_reply indicating success or failure
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_basic_get(amqp_connection_state_t state, amqp_channel_t channel,
+                         amqp_bytes_t queue, amqp_boolean_t no_ack);
+
+/**
+ * Do a basic.reject
+ *
+ * Actively reject a message that has been delivered
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel identifier
+ * \param [in] delivery_tag the delivery tag of the message to reject
+ * \param [in] requeue indicate to the broker whether it should requeue the
+ *              message or just discard it.
+ * \return 0 on success, 0 > on failing to send the reject method to the broker.
+ *          This will not indicate failure if something goes wrong on the broker.
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_basic_reject(amqp_connection_state_t state, amqp_channel_t channel,
+                            uint64_t delivery_tag, amqp_boolean_t requeue);
+
+/**
+ * Do a basic.nack
+ *
+ * Actively reject a message, this has the same effect as amqp_basic_reject()
+ * however, amqp_basic_nack() can negatively acknowledge multiple messages with
+ * one call much like amqp_basic_ack() can acknowledge mutliple messages with
+ * one call.
+ *
+ * \param [in] state the connection object
+ * \param [in] channel the channel identifier
+ * \param [in] delivery_tag the delivery tag of the message to reject
+ * \param [in] multiple if set to 1 negatively acknowledge all unacknowledged
+ *              messages on this channel.
+ * \param [in] requeue indicate to the broker whether it should requeue the
+ *              message or dead-letter it.
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise.
+ *
+ * \since v0.5.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_basic_nack(amqp_connection_state_t state, amqp_channel_t channel,
+                          uint64_t delivery_tag, amqp_boolean_t multiple,
+                          amqp_boolean_t requeue);
+/**
+ * Check to see if there is data left in the receive buffer
+ *
+ * Can be used to see if there is data still in the buffer, if so
+ * calling amqp_simple_wait_frame will not immediately enter a
+ * blocking read.
+ *
+ * \param [in] state the connection object
+ * \return true if there is data in the recieve buffer, false otherwise
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_boolean_t
+AMQP_CALL amqp_data_in_buffer(amqp_connection_state_t state);
+
+/**
+ * Get the error string for the given error code.
+ *
+ * \deprecated This function has been deprecated in favor of
+ *  \ref amqp_error_string2() which returns statically allocated
+ *  string which do not need to be freed by the caller.
+ *
+ * The returned string resides on the heap; the caller is responsible
+ * for freeing it.
+ *
+ * \param [in] err return error code
+ * \return the error string
+ *
+ * \since v0.1
+ */
+AMQP_DEPRECATED(
+  AMQP_PUBLIC_FUNCTION
+  char *
+  AMQP_CALL amqp_error_string(int err)
+);
+
+
+/**
+ * Get the error string for the given error code.
+ *
+ * Get an error string associated with an error code. The string is statically
+ * allocated and does not need to be freed
+ *
+ * \param [in] err the error code
+ * \return the error string
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+const char *
+AMQP_CALL amqp_error_string2(int err);
+
+
+/**
+ * Deserialize an amqp_table_t from AMQP wireformat
+ *
+ * This is an internal function and is not typically used by
+ * client applications
+ *
+ * \param [in] encoded the buffer containing the serialized data
+ * \param [in] pool memory pool used to allocate the table entries from
+ * \param [in] output the amqp_table_t structure to fill in. Any existing
+ *             entries will be erased
+ * \param [in,out] offset The offset into the encoded buffer to start
+ *                 reading the serialized table. It will be updated
+ *                 by this function to end of the table
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure
+ *  Possible error codes:
+ *  - AMQP_STATUS_NO_MEMORY out of memory
+ *  - AMQP_STATUS_BAD_AMQP_DATA invalid wireformat
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_decode_table(amqp_bytes_t encoded, amqp_pool_t *pool,
+                            amqp_table_t *output, size_t *offset);
+
+/**
+ * Serializes an amqp_table_t to the AMQP wireformat
+ *
+ * This is an internal function and is not typically used by
+ * client applications
+ *
+ * \param [in] encoded the buffer where to serialize the table to
+ * \param [in] input the amqp_table_t to serialize
+ * \param [in,out] offset The offset into the encoded buffer to start
+ *                 writing the serialized table. It will be updated
+ *                 by this function to where writing left off
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure
+ *  Possible error codes:
+ *  - AMQP_STATUS_TABLE_TOO_BIG the serialized form is too large for the
+ *    buffer
+ *  - AMQP_STATUS_BAD_AMQP_DATA invalid table
+ *
+ * \since v0.1
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, size_t *offset);
+
+
+/**
+ * Create a deep-copy of an amqp_table_t object
+ *
+ * Creates a deep-copy of an amqp_table_t object, using the provided pool
+ * object to allocate the necessary memory. This memory can be freed later by
+ * call recycle_amqp_pool(), or empty_amqp_pool()
+ *
+ * \param [in] original the table to copy
+ * \param [in,out] clone the table to copy to
+ * \param [in] pool the initialized memory pool to do allocations for the table
+ *             from
+ * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure.
+ *  Possible error values:
+ *  - AMQP_STATUS_NO_MEMORY - memory allocation failure.
+ *  - AMQP_STATUS_INVALID_PARAMETER - invalid table (e.g., no key name)
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_table_clone(amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool);
+
+/**
+ * A message object
+ *
+ * \since v0.4.0
+ */
+typedef struct amqp_message_t_ {
+  amqp_basic_properties_t properties; /**< message properties */
+  amqp_bytes_t body;                  /**< message body */
+  amqp_pool_t pool;                   /**< pool used to allocate properties */
+} amqp_message_t;
+
+/**
+ * Reads the next message on a channel
+ *
+ * Reads a complete message (header + body) on a specified channel. This
+ * function is intended to be used with amqp_basic_get() or when an
+ * AMQP_BASIC_DELIVERY_METHOD method is received.
+ *
+ * \param [in,out] state the connection object
+ * \param [in] channel the channel on which to read the message from
+ * \param [in,out] message a pointer to a amqp_message_t object. Caller should
+ *                 call amqp_message_destroy() when it is done using the
+ *                 fields in the message object.  The caller is responsible for
+ *                 allocating/destroying the amqp_message_t object itself.
+ * \param [in] flags pass in 0. Currently unused.
+ * \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL on success.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_read_message(amqp_connection_state_t state,
+                            amqp_channel_t channel,
+                            amqp_message_t *message, int flags);
+
+/**
+ * Frees memory associated with a amqp_message_t allocated in amqp_read_message
+ *
+ * \param [in] message
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_destroy_message(amqp_message_t *message);
+
+/**
+ * Envelope object
+ *
+ * \since v0.4.0
+ */
+typedef struct amqp_envelope_t_ {
+  amqp_channel_t channel;           /**< channel message was delivered on */
+  amqp_bytes_t consumer_tag;        /**< the consumer tag the message was delivered to */
+  uint64_t delivery_tag;            /**< the messages delivery tag */
+  amqp_boolean_t redelivered;       /**< flag indicating whether this message is being redelivered */
+  amqp_bytes_t exchange;            /**< exchange this message was published to */
+  amqp_bytes_t routing_key;         /**< the routing key this message was published with */
+  amqp_message_t message;           /**< the message */
+} amqp_envelope_t;
+
+/**
+ * Wait for and consume a message
+ *
+ * Waits for a basic.deliver method on any channel, upon receipt of
+ * basic.deliver it reads that message, and returns. If any other method is
+ * received before basic.deliver, this function will return an amqp_rpc_reply_t
+ * with ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, and
+ * ret.library_error == AMQP_STATUS_UNEXPECTED_FRAME. The caller should then
+ * call amqp_simple_wait_frame() to read this frame and take appropriate action.
+ *
+ * This function should be used after starting a consumer with the
+ * amqp_basic_consume() function
+ *
+ * \param [in,out] state the connection object
+ * \param [in,out] envelope a pointer to a amqp_envelope_t object. Caller
+ *                 should call #amqp_destroy_envelope() when it is done using
+ *                 the fields in the envelope object. The caller is responsible
+ *                 for allocating/destroying the amqp_envelope_t object itself.
+ * \param [in] timeout a timeout to wait for a message delivery. Passing in
+ *             NULL will result in blocking behavior.
+ * \param [in] flags pass in 0. Currently unused.
+ * \returns a amqp_rpc_reply_t object.  ret.reply_type == AMQP_RESPONSE_NORMAL
+ *          on success. If ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, and
+ *          ret.library_error == AMQP_STATUS_UNEXPECTED_FRAME, a frame other
+ *          than AMQP_BASIC_DELIVER_METHOD was received, the caller should call
+ *          amqp_simple_wait_frame() to read this frame and take appropriate
+ *          action.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_rpc_reply_t
+AMQP_CALL amqp_consume_message(amqp_connection_state_t state,
+                               amqp_envelope_t *envelope,
+                               struct timeval *timeout, int flags);
+
+/**
+ * Frees memory associated with a amqp_envelope_t allocated in amqp_consume_message()
+ *
+ * \param [in] envelope
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_destroy_envelope(amqp_envelope_t *envelope);
+
+
+/**
+ * Parameters used to connect to the RabbitMQ broker
+ *
+ * \since v0.2
+ */
+struct amqp_connection_info {
+  char *user;                 /**< the username to authenticate with the broker, default on most broker is 'guest' */
+  char *password;             /**< the password to authenticate with the broker, default on most brokers is 'guest' */
+  char *host;                 /**< the hostname of the broker */
+  char *vhost;                /**< the virtual host on the broker to connect to, a good default is "/" */
+  int port;                   /**< the port that the broker is listening on, default on most brokers is 5672 */
+  amqp_boolean_t ssl;
+};
+
+/**
+ * Initialze an amqp_connection_info to default values
+ *
+ * The default values are:
+ * - user: "guest"
+ * - password: "guest"
+ * - host: "localhost"
+ * - vhost: "/"
+ * - port: 5672
+ *
+ * \param [out] parsed the connection info to set defaults on
+ *
+ * \since v0.2
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL amqp_default_connection_info(struct amqp_connection_info *parsed);
+
+/**
+ * Parse a connection URL
+ *
+ * An amqp connection url takes the form:
+ *
+ * amqp://[$USERNAME[:$PASSWORD]\@]$HOST[:$PORT]/[$VHOST]
+ *
+ * Examples:
+ *  amqp://guest:guest\@localhost:5672//
+ *  amqp://guest:guest\@localhost/myvhost
+ *
+ * \note This function modifies url parameter.
+ *
+ * \param [in] url URI to parse, note that this parameter is modified by the
+ *             function.
+ * \param [out] parsed the connection info gleaned from the URI. The char*
+ *              members will point to parts of the url input parameter.
+ *              Memory management will depend on how the url is allocated.
+ * \returns AMQP_STATUS_OK on success, AMQP_STATUS_BAD_URL on failure
+ *
+ * \since v0.2
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_parse_url(char *url, struct amqp_connection_info *parsed);
+
+/* socket API */
+
+/**
+ * Open a socket connection.
+ *
+ * This function opens a socket connection returned from amqp_tcp_socket_new()
+ * or amqp_ssl_socket_new(). This function should be called after setting
+ * socket options and prior to assigning the socket to an AMQP connection with
+ * amqp_set_socket().
+ *
+ * \param [in,out] self A socket object.
+ * \param [in] host Connect to this host.
+ * \param [in] port Connect on this remote port.
+ *
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum on failure
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_socket_open(amqp_socket_t *self, const char *host, int port);
+
+/**
+ * Open a socket connection.
+ *
+ * This function opens a socket connection returned from amqp_tcp_socket_new()
+ * or amqp_ssl_socket_new(). This function should be called after setting
+ * socket options and prior to assigning the socket to an AMQP connection with
+ * amqp_set_socket().
+ *
+ * \param [in,out] self A socket object.
+ * \param [in] host Connect to this host.
+ * \param [in] port Connect on this remote port.
+ * \param [in] timeout Max allowed time to spent on opening. If NULL - run in blocking mode
+ *
+ * \return AMQP_STATUS_OK on success, an amqp_status_enum on failure.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_socket_open_noblock(amqp_socket_t *self, const char *host, int port, struct timeval *timeout);
+
+/**
+ * Get the socket descriptor in use by a socket object.
+ *
+ * Retrieve the underlying socket descriptor. This function can be used to
+ * perform low-level socket operations that aren't supported by the socket
+ * interface. Use with caution!
+ *
+ * \param [in,out] self A socket object.
+ *
+ * \return The underlying socket descriptor, or -1 if there is no socket descriptor
+ *  associated with
+ *  with
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_socket_get_sockfd(amqp_socket_t *self);
+
+/**
+ * Get the socket object associated with a amqp_connection_state_t
+ *
+ * \param [in] state the connection object to get the socket from
+ * \return a pointer to the socket object, or NULL if one has not been assigned
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_socket_t *
+amqp_get_socket(amqp_connection_state_t state);
+
+/**
+ * Get the broker properties table
+ *
+ * \param [in] state the connection object
+ * \return a pointer to an amqp_table_t containing the properties advertised
+ *  by the broker on connection. The connection object owns the table, it
+ *  should not be modified.
+ *
+ * \since v0.5.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_table_t *
+amqp_get_server_properties(amqp_connection_state_t state);
+
+AMQP_END_DECLS
+
+
+#endif /* AMQP_H */
diff --git a/modules/kazoo/deps/amqp_api.c b/modules/kazoo/deps/amqp_api.c
new file mode 100644
index 0000000..1dd303e
--- /dev/null
+++ b/modules/kazoo/deps/amqp_api.c
@@ -0,0 +1,340 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2013
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include "amqp_timer.h"
+#include <assert.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ERROR_MASK (0x00FF)
+#define ERROR_CATEGORY_MASK (0xFF00)
+
+enum error_category_enum_ {
+  EC_base = 0,
+  EC_tcp = 1,
+  EC_ssl = 2
+};
+
+static const char *base_error_strings[] = {
+  "operation completed successfully",   /* AMQP_STATUS_OK                       0x0 */
+  "could not allocate memory",          /* AMQP_STATUS_NO_MEMORY                -0x0001 */
+  "invalid AMQP data",                  /* AMQP_STATUS_BAD_AQMP_DATA            -0x0002 */
+  "unknown AMQP class id",              /* AMQP_STATUS_UNKNOWN_CLASS            -0x0003 */
+  "unknown AMQP method id",             /* AMQP_STATUS_UNKNOWN_METHOD           -0x0004 */
+  "hostname lookup failed",             /* AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED -0x0005 */
+  "incompatible AMQP version",          /* AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION -0x0006 */
+  "connection closed unexpectedly",     /* AMQP_STATUS_CONNECTION_CLOSED        -0x0007 */
+  "could not parse AMQP URL",           /* AMQP_STATUS_BAD_AMQP_URL             -0x0008 */
+  "a socket error occurred",            /* AMQP_STATUS_SOCKET_ERROR             -0x0009 */
+  "invalid parameter",                  /* AMQP_STATUS_INVALID_PARAMETER        -0x000A */
+  "table too large for buffer",         /* AMQP_STATUS_TABLE_TOO_BIG            -0x000B */
+  "unexpected method received",         /* AMQP_STATUS_WRONG_METHOD             -0x000C */
+  "request timed out",                  /* AMQP_STATUS_TIMEOUT                  -0x000D */
+  "system timer has failed",            /* AMQP_STATUS_TIMER_FAILED             -0x000E */
+  "heartbeat timeout, connection closed"/* AMQP_STATUS_HEARTBEAT_TIMEOUT        -0x000F */
+};
+
+static const char *tcp_error_strings[] = {
+  "a socket error occurred",              /* AMQP_STATUS_TCP_ERROR                -0x0100 */
+  "socket library initialization failed"  /* AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR -0x0101 */
+};
+
+static const char *ssl_error_strings[] = {
+  "a SSL error occurred",                 /* AMQP_STATUS_SSL_ERROR                -0x0200 */
+  "SSL hostname verification failed",     /* AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED -0x0201 */
+  "SSL peer cert verification failed",    /* AMQP_STATUS_SSL_PEER_VERIFY_FAILED -0x0202 */
+  "SSL handshake failed"                  /* AMQP_STATUS_SSL_CONNECTION_FAILED  -0x0203 */
+};
+
+static const char *unknown_error_string = "(unknown error)";
+
+const char *amqp_error_string2(int code)
+{
+  const char *error_string;
+  size_t category = (((-code) & ERROR_CATEGORY_MASK) >> 8);
+  size_t error = (-code) & ERROR_MASK;
+
+  switch (category) {
+    case EC_base:
+      if (error < (sizeof(base_error_strings) / sizeof(char *))) {
+        error_string = base_error_strings[error];
+      } else {
+        error_string = unknown_error_string;
+      }
+      break;
+
+    case EC_tcp:
+      if (error < (sizeof(tcp_error_strings) / sizeof(char *))) {
+        error_string = tcp_error_strings[error];
+      } else {
+        error_string = unknown_error_string;
+      }
+      break;
+
+    case EC_ssl:
+      if (error < (sizeof(ssl_error_strings) / sizeof(char *))) {
+        error_string = ssl_error_strings[error];
+      } else {
+        error_string = unknown_error_string;
+      }
+
+      break;
+
+    default:
+      error_string = unknown_error_string;
+      break;
+
+  }
+
+  return error_string;
+}
+
+char *amqp_error_string(int code)
+{
+  /* Previously sometimes clients had to flip the sign on a return value from a
+   * function to get the correct error code. Now, all error codes are negative.
+   * To keep people's legacy code running correctly, we map all error codes to
+   * negative values.
+   *
+   * This is only done with this deprecated function.
+   */
+  if (code > 0) {
+    code = -code;
+  }
+  return strdup(amqp_error_string2(code));
+}
+
+void amqp_abort(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  va_end(ap);
+  fputc('\n', stderr);
+  abort();
+}
+
+const amqp_bytes_t amqp_empty_bytes = { 0, NULL };
+const amqp_table_t amqp_empty_table = { 0, NULL };
+const amqp_array_t amqp_empty_array = { 0, NULL };
+
+#define RPC_REPLY(replytype)\
+  (state->most_recent_api_result.reply_type == AMQP_RESPONSE_NORMAL\
+   ? (replytype *) state->most_recent_api_result.reply.decoded\
+   : NULL)
+
+int amqp_basic_publish(amqp_connection_state_t state,
+                       amqp_channel_t channel,
+                       amqp_bytes_t exchange,
+                       amqp_bytes_t routing_key,
+                       amqp_boolean_t mandatory,
+                       amqp_boolean_t immediate,
+                       amqp_basic_properties_t const *properties,
+                       amqp_bytes_t body)
+{
+  amqp_frame_t f;
+  size_t body_offset;
+  size_t usable_body_payload_size = state->frame_max - (HEADER_SIZE + FOOTER_SIZE);
+  int res;
+
+  amqp_basic_publish_t m;
+  amqp_basic_properties_t default_properties;
+
+  m.exchange = exchange;
+  m.routing_key = routing_key;
+  m.mandatory = mandatory;
+  m.immediate = immediate;
+  m.ticket = 0;
+
+  if (amqp_heartbeat_enabled(state)) {
+    uint64_t current_timestamp = amqp_get_monotonic_timestamp();
+    if (0 == current_timestamp) {
+      return AMQP_STATUS_TIMER_FAILURE;
+    }
+
+    if (current_timestamp > state->next_recv_heartbeat) {
+      res = amqp_try_recv(state, current_timestamp);
+      if (AMQP_STATUS_TIMEOUT == res) {
+        return AMQP_STATUS_HEARTBEAT_TIMEOUT;
+      } else if (AMQP_STATUS_OK != res) {
+        return res;
+      }
+    }
+  }
+
+  res = amqp_send_method(state, channel, AMQP_BASIC_PUBLISH_METHOD, &m);
+  if (res < 0) {
+    return res;
+  }
+
+  if (properties == NULL) {
+    memset(&default_properties, 0, sizeof(default_properties));
+    properties = &default_properties;
+  }
+
+  f.frame_type = AMQP_FRAME_HEADER;
+  f.channel = channel;
+  f.payload.properties.class_id = AMQP_BASIC_CLASS;
+  f.payload.properties.body_size = body.len;
+  f.payload.properties.decoded = (void *) properties;
+
+  res = amqp_send_frame(state, &f);
+  if (res < 0) {
+    return res;
+  }
+
+  body_offset = 0;
+  while (body_offset < body.len) {
+    size_t remaining = body.len - body_offset;
+
+    if (remaining == 0) {
+      break;
+    }
+
+    f.frame_type = AMQP_FRAME_BODY;
+    f.channel = channel;
+    f.payload.body_fragment.bytes = amqp_offset(body.bytes, body_offset);
+    if (remaining >= usable_body_payload_size) {
+      f.payload.body_fragment.len = usable_body_payload_size;
+    } else {
+      f.payload.body_fragment.len = remaining;
+    }
+
+    body_offset += f.payload.body_fragment.len;
+    res = amqp_send_frame(state, &f);
+    if (res < 0) {
+      return res;
+    }
+  }
+
+  return AMQP_STATUS_OK;
+}
+
+amqp_rpc_reply_t amqp_channel_close(amqp_connection_state_t state,
+                                    amqp_channel_t channel,
+                                    int code)
+{
+  char codestr[13];
+  amqp_method_number_t replies[2] = { AMQP_CHANNEL_CLOSE_OK_METHOD, 0};
+  amqp_channel_close_t req;
+
+  req.reply_code = code;
+  req.reply_text.bytes = codestr;
+  req.reply_text.len = sprintf(codestr, "%d", code);
+  req.class_id = 0;
+  req.method_id = 0;
+
+  return amqp_simple_rpc(state, channel, AMQP_CHANNEL_CLOSE_METHOD,
+                         replies, &req);
+}
+
+amqp_rpc_reply_t amqp_connection_close(amqp_connection_state_t state,
+                                       int code)
+{
+  char codestr[13];
+  amqp_method_number_t replies[2] = { AMQP_CONNECTION_CLOSE_OK_METHOD, 0};
+  amqp_channel_close_t req;
+
+  req.reply_code = code;
+  req.reply_text.bytes = codestr;
+  req.reply_text.len = sprintf(codestr, "%d", code);
+  req.class_id = 0;
+  req.method_id = 0;
+
+  return amqp_simple_rpc(state, 0, AMQP_CONNECTION_CLOSE_METHOD,
+                         replies, &req);
+}
+
+int amqp_basic_ack(amqp_connection_state_t state,
+                   amqp_channel_t channel,
+                   uint64_t delivery_tag,
+                   amqp_boolean_t multiple)
+{
+  amqp_basic_ack_t m;
+  m.delivery_tag = delivery_tag;
+  m.multiple = multiple;
+  return amqp_send_method(state, channel, AMQP_BASIC_ACK_METHOD, &m);
+}
+
+amqp_rpc_reply_t amqp_basic_get(amqp_connection_state_t state,
+                                amqp_channel_t channel,
+                                amqp_bytes_t queue,
+                                amqp_boolean_t no_ack)
+{
+  amqp_method_number_t replies[] = { AMQP_BASIC_GET_OK_METHOD,
+                                     AMQP_BASIC_GET_EMPTY_METHOD,
+                                     0
+                                   };
+  amqp_basic_get_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.no_ack = no_ack;
+
+  state->most_recent_api_result = amqp_simple_rpc(state, channel,
+                                  AMQP_BASIC_GET_METHOD,
+                                  replies, &req);
+  return state->most_recent_api_result;
+}
+
+int amqp_basic_reject(amqp_connection_state_t state,
+                      amqp_channel_t channel,
+                      uint64_t delivery_tag,
+                      amqp_boolean_t requeue)
+{
+  amqp_basic_reject_t req;
+  req.delivery_tag = delivery_tag;
+  req.requeue = requeue;
+  return amqp_send_method(state, channel, AMQP_BASIC_REJECT_METHOD, &req);
+}
+
+int amqp_basic_nack(amqp_connection_state_t state, amqp_channel_t channel,
+                          uint64_t delivery_tag, amqp_boolean_t multiple,
+                          amqp_boolean_t requeue)
+{
+  amqp_basic_nack_t req;
+  req.delivery_tag = delivery_tag;
+  req.multiple = multiple;
+  req.requeue = requeue;
+  return amqp_send_method(state, channel, AMQP_BASIC_NACK_METHOD, &req);
+}
diff --git a/modules/kazoo/deps/amqp_connection.c b/modules/kazoo/deps/amqp_connection.c
new file mode 100644
index 0000000..3315969
--- /dev/null
+++ b/modules/kazoo/deps/amqp_connection.c
@@ -0,0 +1,535 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2014
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_tcp_socket.h"
+#include "amqp_private.h"
+#include "amqp_timer.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef AMQP_INITIAL_FRAME_POOL_PAGE_SIZE
+#define AMQP_INITIAL_FRAME_POOL_PAGE_SIZE 65536
+#endif
+
+#ifndef AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE
+#define AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE 131072
+#endif
+
+
+#define ENFORCE_STATE(statevec, statenum)                                                 \
+  {                                                                                       \
+    amqp_connection_state_t _check_state = (statevec);                                    \
+    size_t _wanted_state = (statenum);                                                    \
+    if (_check_state->state != _wanted_state)                                             \
+      amqp_abort("Programming error: invalid AMQP connection state: expected %d, got %d", \
+                 _wanted_state,                                                           \
+                 _check_state->state);                                                    \
+  }
+
+amqp_connection_state_t amqp_new_connection(void)
+{
+  int res;
+  amqp_connection_state_t state =
+    (amqp_connection_state_t) calloc(1, sizeof(struct amqp_connection_state_t_));
+
+  if (state == NULL) {
+    return NULL;
+  }
+
+  res = amqp_tune_connection(state, 0, AMQP_INITIAL_FRAME_POOL_PAGE_SIZE, 0);
+  if (0 != res) {
+    goto out_nomem;
+  }
+
+  state->inbound_buffer.bytes = state->header_buffer;
+  state->inbound_buffer.len = sizeof(state->header_buffer);
+
+  state->state = CONNECTION_STATE_INITIAL;
+  /* the server protocol version response is 8 bytes, which conveniently
+     is also the minimum frame size */
+  state->target_size = 8;
+
+  state->sock_inbound_buffer.len = AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE;
+  state->sock_inbound_buffer.bytes = malloc(AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE);
+  if (state->sock_inbound_buffer.bytes == NULL) {
+    goto out_nomem;
+  }
+
+  init_amqp_pool(&state->properties_pool, 512);
+
+  return state;
+
+out_nomem:
+  free(state->sock_inbound_buffer.bytes);
+  free(state);
+  return NULL;
+}
+
+int amqp_get_sockfd(amqp_connection_state_t state)
+{
+  return state->socket ? amqp_socket_get_sockfd(state->socket) : -1;
+}
+
+void amqp_set_sockfd(amqp_connection_state_t state,
+                     int sockfd)
+{
+  amqp_socket_t *socket = amqp_tcp_socket_new(state);
+  if (!socket) {
+    amqp_abort("%s", strerror(errno));
+  }
+  amqp_tcp_socket_set_sockfd(socket, sockfd);
+}
+
+void amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket)
+{
+  amqp_socket_delete(state->socket);
+  state->socket = socket;
+}
+
+amqp_socket_t *
+amqp_get_socket(amqp_connection_state_t state)
+{
+  return state->socket;
+}
+
+int amqp_tune_connection(amqp_connection_state_t state,
+                         int channel_max,
+                         int frame_max,
+                         int heartbeat)
+{
+  void *newbuf;
+
+  ENFORCE_STATE(state, CONNECTION_STATE_IDLE);
+
+  state->channel_max = channel_max;
+  state->frame_max = frame_max;
+  state->heartbeat = heartbeat;
+
+  if (amqp_heartbeat_enabled(state)) {
+    uint64_t current_time = amqp_get_monotonic_timestamp();
+    if (0 == current_time) {
+      return AMQP_STATUS_TIMER_FAILURE;
+    }
+    state->next_send_heartbeat = amqp_calc_next_send_heartbeat(state, current_time);
+    state->next_recv_heartbeat = amqp_calc_next_recv_heartbeat(state, current_time);
+  }
+
+  state->outbound_buffer.len = frame_max;
+  newbuf = realloc(state->outbound_buffer.bytes, frame_max);
+  if (newbuf == NULL) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+  state->outbound_buffer.bytes = newbuf;
+
+  return AMQP_STATUS_OK;
+}
+
+int amqp_get_channel_max(amqp_connection_state_t state)
+{
+  return state->channel_max;
+}
+
+int amqp_destroy_connection(amqp_connection_state_t state)
+{
+  int status = AMQP_STATUS_OK;
+  if (state) {
+    int i;
+    for (i = 0; i < POOL_TABLE_SIZE; ++i) {
+      amqp_pool_table_entry_t *entry = state->pool_table[i];
+      while (NULL != entry) {
+        amqp_pool_table_entry_t *todelete = entry;
+        empty_amqp_pool(&entry->pool);
+        entry = entry->next;
+        free(todelete);
+      }
+    }
+
+    free(state->outbound_buffer.bytes);
+    free(state->sock_inbound_buffer.bytes);
+    amqp_socket_delete(state->socket);
+    empty_amqp_pool(&state->properties_pool);
+    free(state);
+  }
+  return status;
+}
+
+static void return_to_idle(amqp_connection_state_t state)
+{
+  state->inbound_buffer.len = sizeof(state->header_buffer);
+  state->inbound_buffer.bytes = state->header_buffer;
+  state->inbound_offset = 0;
+  state->target_size = HEADER_SIZE;
+  state->state = CONNECTION_STATE_IDLE;
+}
+
+static size_t consume_data(amqp_connection_state_t state,
+                           amqp_bytes_t *received_data)
+{
+  /* how much data is available and will fit? */
+  size_t bytes_consumed = state->target_size - state->inbound_offset;
+  if (received_data->len < bytes_consumed) {
+    bytes_consumed = received_data->len;
+  }
+
+  memcpy(amqp_offset(state->inbound_buffer.bytes, state->inbound_offset),
+         received_data->bytes, bytes_consumed);
+  state->inbound_offset += bytes_consumed;
+  received_data->bytes = amqp_offset(received_data->bytes, bytes_consumed);
+  received_data->len -= bytes_consumed;
+
+  return bytes_consumed;
+}
+
+int amqp_handle_input(amqp_connection_state_t state,
+                      amqp_bytes_t received_data,
+                      amqp_frame_t *decoded_frame)
+{
+  size_t bytes_consumed;
+  void *raw_frame;
+
+  /* Returning frame_type of zero indicates either insufficient input,
+     or a complete, ignored frame was read. */
+  decoded_frame->frame_type = 0;
+
+  if (received_data.len == 0) {
+    return AMQP_STATUS_OK;
+  }
+
+  if (state->state == CONNECTION_STATE_IDLE) {
+    state->state = CONNECTION_STATE_HEADER;
+  }
+
+  bytes_consumed = consume_data(state, &received_data);
+
+  /* do we have target_size data yet? if not, return with the
+     expectation that more will arrive */
+  if (state->inbound_offset < state->target_size) {
+    return bytes_consumed;
+  }
+
+  raw_frame = state->inbound_buffer.bytes;
+
+  switch (state->state) {
+  case CONNECTION_STATE_INITIAL:
+    /* check for a protocol header from the server */
+    if (memcmp(raw_frame, "AMQP", 4) == 0) {
+      decoded_frame->frame_type = AMQP_PSEUDOFRAME_PROTOCOL_HEADER;
+      decoded_frame->channel = 0;
+
+      decoded_frame->payload.protocol_header.transport_high
+        = amqp_d8(raw_frame, 4);
+      decoded_frame->payload.protocol_header.transport_low
+        = amqp_d8(raw_frame, 5);
+      decoded_frame->payload.protocol_header.protocol_version_major
+        = amqp_d8(raw_frame, 6);
+      decoded_frame->payload.protocol_header.protocol_version_minor
+        = amqp_d8(raw_frame, 7);
+
+      return_to_idle(state);
+      return bytes_consumed;
+    }
+
+    /* it's not a protocol header; fall through to process it as a
+       regular frame header */
+
+  case CONNECTION_STATE_HEADER: {
+    amqp_channel_t channel;
+    amqp_pool_t *channel_pool;
+    /* frame length is 3 bytes in */
+    channel = amqp_d16(raw_frame, 1);
+
+    state->target_size
+      = amqp_d32(raw_frame, 3) + HEADER_SIZE + FOOTER_SIZE;
+
+    if ((size_t)state->frame_max < state->target_size) {
+      return AMQP_STATUS_BAD_AMQP_DATA;
+    }
+
+    channel_pool = amqp_get_or_create_channel_pool(state, channel);
+    if (NULL == channel_pool) {
+      return AMQP_STATUS_NO_MEMORY;
+    }
+
+    amqp_pool_alloc_bytes(channel_pool, state->target_size, &state->inbound_buffer);
+    if (NULL == state->inbound_buffer.bytes) {
+      return AMQP_STATUS_NO_MEMORY;
+    }
+    memcpy(state->inbound_buffer.bytes, state->header_buffer, HEADER_SIZE);
+    raw_frame = state->inbound_buffer.bytes;
+
+    state->state = CONNECTION_STATE_BODY;
+
+    bytes_consumed += consume_data(state, &received_data);
+
+    /* do we have target_size data yet? if not, return with the
+       expectation that more will arrive */
+    if (state->inbound_offset < state->target_size) {
+      return bytes_consumed;
+    }
+
+  }
+    /* fall through to process body */
+
+  case CONNECTION_STATE_BODY: {
+    amqp_bytes_t encoded;
+    int res;
+    amqp_pool_t *channel_pool;
+
+    /* Check frame end marker (footer) */
+    if (amqp_d8(raw_frame, state->target_size - 1) != AMQP_FRAME_END) {
+      return AMQP_STATUS_BAD_AMQP_DATA;
+    }
+
+    decoded_frame->frame_type = amqp_d8(raw_frame, 0);
+    decoded_frame->channel = amqp_d16(raw_frame, 1);
+
+    channel_pool = amqp_get_or_create_channel_pool(state, decoded_frame->channel);
+    if (NULL == channel_pool) {
+      return AMQP_STATUS_NO_MEMORY;
+    }
+
+    switch (decoded_frame->frame_type) {
+    case AMQP_FRAME_METHOD:
+      decoded_frame->payload.method.id = amqp_d32(raw_frame, HEADER_SIZE);
+      encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 4);
+      encoded.len = state->target_size - HEADER_SIZE - 4 - FOOTER_SIZE;
+
+      res = amqp_decode_method(decoded_frame->payload.method.id,
+                               channel_pool, encoded,
+                               &decoded_frame->payload.method.decoded);
+      if (res < 0) {
+        return res;
+      }
+
+      break;
+
+    case AMQP_FRAME_HEADER:
+      decoded_frame->payload.properties.class_id
+        = amqp_d16(raw_frame, HEADER_SIZE);
+      /* unused 2-byte weight field goes here */
+      decoded_frame->payload.properties.body_size
+        = amqp_d64(raw_frame, HEADER_SIZE + 4);
+      encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 12);
+      encoded.len = state->target_size - HEADER_SIZE - 12 - FOOTER_SIZE;
+      decoded_frame->payload.properties.raw = encoded;
+
+      res = amqp_decode_properties(decoded_frame->payload.properties.class_id,
+                                   channel_pool, encoded,
+                                   &decoded_frame->payload.properties.decoded);
+      if (res < 0) {
+        return res;
+      }
+
+      break;
+
+    case AMQP_FRAME_BODY:
+      decoded_frame->payload.body_fragment.len
+        = state->target_size - HEADER_SIZE - FOOTER_SIZE;
+      decoded_frame->payload.body_fragment.bytes
+        = amqp_offset(raw_frame, HEADER_SIZE);
+      break;
+
+    case AMQP_FRAME_HEARTBEAT:
+      break;
+
+    default:
+      /* Ignore the frame */
+      decoded_frame->frame_type = 0;
+      break;
+    }
+
+    return_to_idle(state);
+    return bytes_consumed;
+  }
+
+  default:
+    amqp_abort("Internal error: invalid amqp_connection_state_t->state %d", state->state);
+    return bytes_consumed;
+  }
+}
+
+amqp_boolean_t amqp_release_buffers_ok(amqp_connection_state_t state)
+{
+  return (state->state == CONNECTION_STATE_IDLE);
+}
+
+void amqp_release_buffers(amqp_connection_state_t state)
+{
+  int i;
+  ENFORCE_STATE(state, CONNECTION_STATE_IDLE);
+
+  for (i = 0; i < POOL_TABLE_SIZE; ++i) {
+    amqp_pool_table_entry_t *entry = state->pool_table[i];
+
+    for ( ;NULL != entry; entry = entry->next) {
+      amqp_maybe_release_buffers_on_channel(state, entry->channel);
+    }
+  }
+}
+
+void amqp_maybe_release_buffers(amqp_connection_state_t state)
+{
+  if (amqp_release_buffers_ok(state)) {
+    amqp_release_buffers(state);
+  }
+}
+
+void amqp_maybe_release_buffers_on_channel(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_link_t *queued_link;
+  amqp_pool_t *pool;
+  if (CONNECTION_STATE_IDLE != state->state) {
+    return;
+  }
+
+  queued_link = state->first_queued_frame;
+
+  while (NULL != queued_link) {
+    amqp_frame_t *frame = queued_link->data;
+    if (channel == frame->channel) {
+      return;
+    }
+
+    queued_link = queued_link->next;
+  }
+
+  pool = amqp_get_channel_pool(state, channel);
+
+  if (pool != NULL) {
+    recycle_amqp_pool(pool);
+  }
+}
+
+int amqp_send_frame(amqp_connection_state_t state,
+                    const amqp_frame_t *frame)
+{
+  void *out_frame = state->outbound_buffer.bytes;
+  int res;
+
+  amqp_e8(out_frame, 0, frame->frame_type);
+  amqp_e16(out_frame, 1, frame->channel);
+
+  if (frame->frame_type == AMQP_FRAME_BODY) {
+    /* For a body frame, rather than copying data around, we use
+       writev to compose the frame */
+    struct iovec iov[3];
+    uint8_t frame_end_byte = AMQP_FRAME_END;
+    const amqp_bytes_t *body = &frame->payload.body_fragment;
+
+    amqp_e32(out_frame, 3, body->len);
+
+    iov[0].iov_base = out_frame;
+    iov[0].iov_len = HEADER_SIZE;
+    iov[1].iov_base = body->bytes;
+    iov[1].iov_len = body->len;
+    iov[2].iov_base = &frame_end_byte;
+    iov[2].iov_len = FOOTER_SIZE;
+
+    res = amqp_socket_writev(state->socket, iov, 3);
+  } else {
+    size_t out_frame_len;
+    amqp_bytes_t encoded;
+
+    switch (frame->frame_type) {
+    case AMQP_FRAME_METHOD:
+      amqp_e32(out_frame, HEADER_SIZE, frame->payload.method.id);
+
+      encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 4);
+      encoded.len = state->outbound_buffer.len - HEADER_SIZE - 4 - FOOTER_SIZE;
+
+      res = amqp_encode_method(frame->payload.method.id,
+                               frame->payload.method.decoded, encoded);
+      if (res < 0) {
+        return res;
+      }
+
+      out_frame_len = res + 4;
+      break;
+
+    case AMQP_FRAME_HEADER:
+      amqp_e16(out_frame, HEADER_SIZE, frame->payload.properties.class_id);
+      amqp_e16(out_frame, HEADER_SIZE+2, 0); /* "weight" */
+      amqp_e64(out_frame, HEADER_SIZE+4, frame->payload.properties.body_size);
+
+      encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 12);
+      encoded.len = state->outbound_buffer.len - HEADER_SIZE - 12 - FOOTER_SIZE;
+
+      res = amqp_encode_properties(frame->payload.properties.class_id,
+                                   frame->payload.properties.decoded, encoded);
+      if (res < 0) {
+        return res;
+      }
+
+      out_frame_len = res + 12;
+      break;
+
+    case AMQP_FRAME_HEARTBEAT:
+      out_frame_len = 0;
+      break;
+
+    default:
+      return AMQP_STATUS_INVALID_PARAMETER;
+    }
+
+    amqp_e32(out_frame, 3, out_frame_len);
+    amqp_e8(out_frame, out_frame_len + HEADER_SIZE, AMQP_FRAME_END);
+    res = amqp_socket_send(state->socket, out_frame,
+                           out_frame_len + HEADER_SIZE + FOOTER_SIZE);
+  }
+
+  if (state->heartbeat > 0) {
+    uint64_t current_time = amqp_get_monotonic_timestamp();
+    if (0 == current_time) {
+      return AMQP_STATUS_TIMER_FAILURE;
+    }
+    state->next_send_heartbeat = amqp_calc_next_send_heartbeat(state, current_time);
+  }
+
+  return res;
+}
+amqp_table_t *
+amqp_get_server_properties(amqp_connection_state_t state)
+{
+  return &state->server_properties;
+}
diff --git a/modules/kazoo/deps/amqp_consumer.c b/modules/kazoo/deps/amqp_consumer.c
new file mode 100644
index 0000000..cf08fd5
--- /dev/null
+++ b/modules/kazoo/deps/amqp_consumer.c
@@ -0,0 +1,308 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2013-2014
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+#include "amqp.h"
+#include "amqp_private.h"
+#include "amqp_socket.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static
+int amqp_basic_properties_clone(amqp_basic_properties_t *original,
+                                amqp_basic_properties_t *clone,
+                                amqp_pool_t *pool)
+{
+  memset(clone, 0, sizeof(amqp_basic_properties_t));
+  clone->_flags = original->_flags;
+
+#define CLONE_BYTES_POOL(original, clone, pool)         \
+  if (0 == original.len) {                              \
+    clone = amqp_empty_bytes;                           \
+  } else {                                              \
+    amqp_pool_alloc_bytes(pool, original.len, &clone);  \
+    if (NULL == clone.bytes) {                          \
+      return AMQP_STATUS_NO_MEMORY;                     \
+    }                                                   \
+    memcpy(clone.bytes, original.bytes, clone.len);     \
+  }
+
+  if (clone->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
+    CLONE_BYTES_POOL(original->content_type, clone->content_type, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) {
+    CLONE_BYTES_POOL(original->content_encoding, clone->content_encoding, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_HEADERS_FLAG) {
+    int res = amqp_table_clone(&original->headers, &clone->headers, pool);
+    if (AMQP_STATUS_OK != res) {
+      return res;
+    }
+  }
+
+  if (clone->_flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
+    clone->delivery_mode = original->delivery_mode;
+  }
+
+  if (clone->_flags & AMQP_BASIC_PRIORITY_FLAG) {
+    clone->priority = original->priority;
+  }
+
+  if (clone->_flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
+    CLONE_BYTES_POOL(original->correlation_id, clone->correlation_id, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_REPLY_TO_FLAG) {
+    CLONE_BYTES_POOL(original->reply_to, clone->reply_to, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_EXPIRATION_FLAG) {
+    CLONE_BYTES_POOL(original->expiration, clone->expiration, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_MESSAGE_ID_FLAG) {
+    CLONE_BYTES_POOL(original->message_id, clone->message_id, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_TIMESTAMP_FLAG) {
+    clone->timestamp = original->timestamp;
+  }
+
+  if (clone->_flags & AMQP_BASIC_TYPE_FLAG) {
+    CLONE_BYTES_POOL(original->type, clone->type, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_USER_ID_FLAG) {
+    CLONE_BYTES_POOL(original->user_id, clone->user_id, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_APP_ID_FLAG) {
+    CLONE_BYTES_POOL(original->app_id, clone->app_id, pool)
+  }
+
+  if (clone->_flags & AMQP_BASIC_CLUSTER_ID_FLAG) {
+    CLONE_BYTES_POOL(original->cluster_id, clone->cluster_id, pool)
+  }
+
+  return AMQP_STATUS_OK;
+#undef CLONE_BYTES_POOL
+}
+
+
+void amqp_destroy_message(amqp_message_t *message)
+{
+  empty_amqp_pool(&message->pool);
+  amqp_bytes_free(message->body);
+}
+
+void amqp_destroy_envelope(amqp_envelope_t *envelope)
+{
+  amqp_destroy_message(&envelope->message);
+  amqp_bytes_free(envelope->routing_key);
+  amqp_bytes_free(envelope->exchange);
+  amqp_bytes_free(envelope->consumer_tag);
+}
+
+static
+int amqp_bytes_malloc_dup_failed(amqp_bytes_t bytes) {
+  if (bytes.len != 0 && bytes.bytes == NULL) {
+    return 1;
+  }
+  return 0;
+}
+
+amqp_rpc_reply_t
+amqp_consume_message(amqp_connection_state_t state, amqp_envelope_t *envelope,
+                     struct timeval *timeout, AMQP_UNUSED int flags)
+{
+  int res;
+  amqp_frame_t frame;
+  amqp_basic_deliver_t *delivery_method;
+  amqp_rpc_reply_t ret;
+
+  memset(&ret, 0, sizeof(amqp_rpc_reply_t));
+  memset(envelope, 0, sizeof(amqp_envelope_t));
+
+  res = amqp_simple_wait_frame_noblock(state, &frame, timeout);
+  if (AMQP_STATUS_OK != res) {
+    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+    ret.library_error = res;
+    goto error_out1;
+  }
+
+  if (AMQP_FRAME_METHOD != frame.frame_type
+      || AMQP_BASIC_DELIVER_METHOD != frame.payload.method.id) {
+    amqp_put_back_frame(state, &frame);
+    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+    ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;
+    goto error_out1;
+  }
+
+  delivery_method = frame.payload.method.decoded;
+
+  envelope->channel = frame.channel;
+  envelope->consumer_tag = amqp_bytes_malloc_dup(delivery_method->consumer_tag);
+  envelope->delivery_tag = delivery_method->delivery_tag;
+  envelope->redelivered = delivery_method->redelivered;
+  envelope->exchange = amqp_bytes_malloc_dup(delivery_method->exchange);
+  envelope->routing_key = amqp_bytes_malloc_dup(delivery_method->routing_key);
+
+  if (amqp_bytes_malloc_dup_failed(envelope->consumer_tag) ||
+      amqp_bytes_malloc_dup_failed(envelope->exchange) ||
+      amqp_bytes_malloc_dup_failed(envelope->routing_key)) {
+    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+    ret.library_error = AMQP_STATUS_NO_MEMORY;
+    goto error_out2;
+  }
+
+  ret = amqp_read_message(state, envelope->channel, &envelope->message, 0);
+  if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
+    goto error_out2;
+  }
+
+  ret.reply_type = AMQP_RESPONSE_NORMAL;
+  return ret;
+
+error_out2:
+  amqp_bytes_free(envelope->routing_key);
+  amqp_bytes_free(envelope->exchange);
+  amqp_bytes_free(envelope->consumer_tag);
+error_out1:
+  return ret;
+}
+
+amqp_rpc_reply_t amqp_read_message(amqp_connection_state_t state,
+                                   amqp_channel_t channel,
+                                   amqp_message_t *message,
+                                   AMQP_UNUSED int flags)
+{
+  amqp_frame_t frame;
+  amqp_rpc_reply_t ret;
+
+  size_t body_read;
+  char *body_read_ptr;
+  int res;
+
+  memset(&ret, 0, sizeof(amqp_rpc_reply_t));
+  memset(message, 0, sizeof(amqp_message_t));
+
+  res = amqp_simple_wait_frame_on_channel(state, channel, &frame);
+  if (AMQP_STATUS_OK != res) {
+    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+    ret.library_error = res;
+
+    goto error_out1;
+  }
+
+  if (AMQP_FRAME_HEADER != frame.frame_type) {
+    if (AMQP_FRAME_METHOD == frame.frame_type &&
+        (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
+         AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {
+
+      ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
+      ret.reply = frame.payload.method;
+
+    } else {
+      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+      ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;
+
+      amqp_put_back_frame(state, &frame);
+    }
+    goto error_out1;
+  }
+
+  init_amqp_pool(&message->pool, 4096);
+  res = amqp_basic_properties_clone(frame.payload.properties.decoded,
+                                    &message->properties, &message->pool);
+
+  if (AMQP_STATUS_OK != res) {
+    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+    ret.library_error = res;
+    goto error_out3;
+  }
+
+  if (0 == frame.payload.properties.body_size) {
+    message->body = amqp_empty_bytes;
+  } else {
+    message->body = amqp_bytes_malloc(frame.payload.properties.body_size);
+    if (NULL == message->body.bytes) {
+      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+      ret.library_error = AMQP_STATUS_NO_MEMORY;
+      goto error_out1;
+    }
+  }
+
+  body_read = 0;
+  body_read_ptr = message->body.bytes;
+
+  while (body_read < message->body.len) {
+    res = amqp_simple_wait_frame_on_channel(state, channel, &frame);
+    if (AMQP_STATUS_OK != res) {
+      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+      ret.library_error = res;
+      goto error_out2;
+    }
+    if (AMQP_FRAME_BODY != frame.frame_type) {
+      if (AMQP_FRAME_METHOD == frame.frame_type &&
+          (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
+           AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {
+
+        ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
+        ret.reply = frame.payload.method;
+      } else {
+        ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+        ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      goto error_out2;
+    }
+
+    if (body_read + frame.payload.body_fragment.len > message->body.len) {
+      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+      ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
+      goto error_out2;
+    }
+
+    memcpy(body_read_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len);
+
+    body_read += frame.payload.body_fragment.len;
+    body_read_ptr += frame.payload.body_fragment.len;
+  }
+
+  ret.reply_type = AMQP_RESPONSE_NORMAL;
+  return ret;
+
+error_out2:
+  amqp_bytes_free(message->body);
+error_out3:
+  empty_amqp_pool(&message->pool);
+error_out1:
+  return ret;
+}
diff --git a/modules/kazoo/deps/amqp_framing.c b/modules/kazoo/deps/amqp_framing.c
new file mode 100644
index 0000000..b2f0a83
--- /dev/null
+++ b/modules/kazoo/deps/amqp_framing.c
@@ -0,0 +1,2102 @@
+/* Generated code. Do not edit. Edit and re-run codegen.py instead.
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2013
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+char const *amqp_constant_name(int constantNumber) {
+  switch (constantNumber) {
+    case AMQP_FRAME_METHOD: return "AMQP_FRAME_METHOD";
+    case AMQP_FRAME_HEADER: return "AMQP_FRAME_HEADER";
+    case AMQP_FRAME_BODY: return "AMQP_FRAME_BODY";
+    case AMQP_FRAME_HEARTBEAT: return "AMQP_FRAME_HEARTBEAT";
+    case AMQP_FRAME_MIN_SIZE: return "AMQP_FRAME_MIN_SIZE";
+    case AMQP_FRAME_END: return "AMQP_FRAME_END";
+    case AMQP_REPLY_SUCCESS: return "AMQP_REPLY_SUCCESS";
+    case AMQP_CONTENT_TOO_LARGE: return "AMQP_CONTENT_TOO_LARGE";
+    case AMQP_NO_ROUTE: return "AMQP_NO_ROUTE";
+    case AMQP_NO_CONSUMERS: return "AMQP_NO_CONSUMERS";
+    case AMQP_ACCESS_REFUSED: return "AMQP_ACCESS_REFUSED";
+    case AMQP_NOT_FOUND: return "AMQP_NOT_FOUND";
+    case AMQP_RESOURCE_LOCKED: return "AMQP_RESOURCE_LOCKED";
+    case AMQP_PRECONDITION_FAILED: return "AMQP_PRECONDITION_FAILED";
+    case AMQP_CONNECTION_FORCED: return "AMQP_CONNECTION_FORCED";
+    case AMQP_INVALID_PATH: return "AMQP_INVALID_PATH";
+    case AMQP_FRAME_ERROR: return "AMQP_FRAME_ERROR";
+    case AMQP_SYNTAX_ERROR: return "AMQP_SYNTAX_ERROR";
+    case AMQP_COMMAND_INVALID: return "AMQP_COMMAND_INVALID";
+    case AMQP_CHANNEL_ERROR: return "AMQP_CHANNEL_ERROR";
+    case AMQP_UNEXPECTED_FRAME: return "AMQP_UNEXPECTED_FRAME";
+    case AMQP_RESOURCE_ERROR: return "AMQP_RESOURCE_ERROR";
+    case AMQP_NOT_ALLOWED: return "AMQP_NOT_ALLOWED";
+    case AMQP_NOT_IMPLEMENTED: return "AMQP_NOT_IMPLEMENTED";
+    case AMQP_INTERNAL_ERROR: return "AMQP_INTERNAL_ERROR";
+    default: return "(unknown)";
+  }
+}
+
+amqp_boolean_t amqp_constant_is_hard_error(int constantNumber) {
+  switch (constantNumber) {
+    case AMQP_CONNECTION_FORCED: return 1;
+    case AMQP_INVALID_PATH: return 1;
+    case AMQP_FRAME_ERROR: return 1;
+    case AMQP_SYNTAX_ERROR: return 1;
+    case AMQP_COMMAND_INVALID: return 1;
+    case AMQP_CHANNEL_ERROR: return 1;
+    case AMQP_UNEXPECTED_FRAME: return 1;
+    case AMQP_RESOURCE_ERROR: return 1;
+    case AMQP_NOT_ALLOWED: return 1;
+    case AMQP_NOT_IMPLEMENTED: return 1;
+    case AMQP_INTERNAL_ERROR: return 1;
+    default: return 0;
+  }
+}
+
+char const *amqp_method_name(amqp_method_number_t methodNumber) {
+  switch (methodNumber) {
+    case AMQP_CONNECTION_START_METHOD: return "AMQP_CONNECTION_START_METHOD";
+    case AMQP_CONNECTION_START_OK_METHOD: return "AMQP_CONNECTION_START_OK_METHOD";
+    case AMQP_CONNECTION_SECURE_METHOD: return "AMQP_CONNECTION_SECURE_METHOD";
+    case AMQP_CONNECTION_SECURE_OK_METHOD: return "AMQP_CONNECTION_SECURE_OK_METHOD";
+    case AMQP_CONNECTION_TUNE_METHOD: return "AMQP_CONNECTION_TUNE_METHOD";
+    case AMQP_CONNECTION_TUNE_OK_METHOD: return "AMQP_CONNECTION_TUNE_OK_METHOD";
+    case AMQP_CONNECTION_OPEN_METHOD: return "AMQP_CONNECTION_OPEN_METHOD";
+    case AMQP_CONNECTION_OPEN_OK_METHOD: return "AMQP_CONNECTION_OPEN_OK_METHOD";
+    case AMQP_CONNECTION_CLOSE_METHOD: return "AMQP_CONNECTION_CLOSE_METHOD";
+    case AMQP_CONNECTION_CLOSE_OK_METHOD: return "AMQP_CONNECTION_CLOSE_OK_METHOD";
+    case AMQP_CONNECTION_BLOCKED_METHOD: return "AMQP_CONNECTION_BLOCKED_METHOD";
+    case AMQP_CONNECTION_UNBLOCKED_METHOD: return "AMQP_CONNECTION_UNBLOCKED_METHOD";
+    case AMQP_CHANNEL_OPEN_METHOD: return "AMQP_CHANNEL_OPEN_METHOD";
+    case AMQP_CHANNEL_OPEN_OK_METHOD: return "AMQP_CHANNEL_OPEN_OK_METHOD";
+    case AMQP_CHANNEL_FLOW_METHOD: return "AMQP_CHANNEL_FLOW_METHOD";
+    case AMQP_CHANNEL_FLOW_OK_METHOD: return "AMQP_CHANNEL_FLOW_OK_METHOD";
+    case AMQP_CHANNEL_CLOSE_METHOD: return "AMQP_CHANNEL_CLOSE_METHOD";
+    case AMQP_CHANNEL_CLOSE_OK_METHOD: return "AMQP_CHANNEL_CLOSE_OK_METHOD";
+    case AMQP_ACCESS_REQUEST_METHOD: return "AMQP_ACCESS_REQUEST_METHOD";
+    case AMQP_ACCESS_REQUEST_OK_METHOD: return "AMQP_ACCESS_REQUEST_OK_METHOD";
+    case AMQP_EXCHANGE_DECLARE_METHOD: return "AMQP_EXCHANGE_DECLARE_METHOD";
+    case AMQP_EXCHANGE_DECLARE_OK_METHOD: return "AMQP_EXCHANGE_DECLARE_OK_METHOD";
+    case AMQP_EXCHANGE_DELETE_METHOD: return "AMQP_EXCHANGE_DELETE_METHOD";
+    case AMQP_EXCHANGE_DELETE_OK_METHOD: return "AMQP_EXCHANGE_DELETE_OK_METHOD";
+    case AMQP_EXCHANGE_BIND_METHOD: return "AMQP_EXCHANGE_BIND_METHOD";
+    case AMQP_EXCHANGE_BIND_OK_METHOD: return "AMQP_EXCHANGE_BIND_OK_METHOD";
+    case AMQP_EXCHANGE_UNBIND_METHOD: return "AMQP_EXCHANGE_UNBIND_METHOD";
+    case AMQP_EXCHANGE_UNBIND_OK_METHOD: return "AMQP_EXCHANGE_UNBIND_OK_METHOD";
+    case AMQP_QUEUE_DECLARE_METHOD: return "AMQP_QUEUE_DECLARE_METHOD";
+    case AMQP_QUEUE_DECLARE_OK_METHOD: return "AMQP_QUEUE_DECLARE_OK_METHOD";
+    case AMQP_QUEUE_BIND_METHOD: return "AMQP_QUEUE_BIND_METHOD";
+    case AMQP_QUEUE_BIND_OK_METHOD: return "AMQP_QUEUE_BIND_OK_METHOD";
+    case AMQP_QUEUE_PURGE_METHOD: return "AMQP_QUEUE_PURGE_METHOD";
+    case AMQP_QUEUE_PURGE_OK_METHOD: return "AMQP_QUEUE_PURGE_OK_METHOD";
+    case AMQP_QUEUE_DELETE_METHOD: return "AMQP_QUEUE_DELETE_METHOD";
+    case AMQP_QUEUE_DELETE_OK_METHOD: return "AMQP_QUEUE_DELETE_OK_METHOD";
+    case AMQP_QUEUE_UNBIND_METHOD: return "AMQP_QUEUE_UNBIND_METHOD";
+    case AMQP_QUEUE_UNBIND_OK_METHOD: return "AMQP_QUEUE_UNBIND_OK_METHOD";
+    case AMQP_BASIC_QOS_METHOD: return "AMQP_BASIC_QOS_METHOD";
+    case AMQP_BASIC_QOS_OK_METHOD: return "AMQP_BASIC_QOS_OK_METHOD";
+    case AMQP_BASIC_CONSUME_METHOD: return "AMQP_BASIC_CONSUME_METHOD";
+    case AMQP_BASIC_CONSUME_OK_METHOD: return "AMQP_BASIC_CONSUME_OK_METHOD";
+    case AMQP_BASIC_CANCEL_METHOD: return "AMQP_BASIC_CANCEL_METHOD";
+    case AMQP_BASIC_CANCEL_OK_METHOD: return "AMQP_BASIC_CANCEL_OK_METHOD";
+    case AMQP_BASIC_PUBLISH_METHOD: return "AMQP_BASIC_PUBLISH_METHOD";
+    case AMQP_BASIC_RETURN_METHOD: return "AMQP_BASIC_RETURN_METHOD";
+    case AMQP_BASIC_DELIVER_METHOD: return "AMQP_BASIC_DELIVER_METHOD";
+    case AMQP_BASIC_GET_METHOD: return "AMQP_BASIC_GET_METHOD";
+    case AMQP_BASIC_GET_OK_METHOD: return "AMQP_BASIC_GET_OK_METHOD";
+    case AMQP_BASIC_GET_EMPTY_METHOD: return "AMQP_BASIC_GET_EMPTY_METHOD";
+    case AMQP_BASIC_ACK_METHOD: return "AMQP_BASIC_ACK_METHOD";
+    case AMQP_BASIC_REJECT_METHOD: return "AMQP_BASIC_REJECT_METHOD";
+    case AMQP_BASIC_RECOVER_ASYNC_METHOD: return "AMQP_BASIC_RECOVER_ASYNC_METHOD";
+    case AMQP_BASIC_RECOVER_METHOD: return "AMQP_BASIC_RECOVER_METHOD";
+    case AMQP_BASIC_RECOVER_OK_METHOD: return "AMQP_BASIC_RECOVER_OK_METHOD";
+    case AMQP_BASIC_NACK_METHOD: return "AMQP_BASIC_NACK_METHOD";
+    case AMQP_TX_SELECT_METHOD: return "AMQP_TX_SELECT_METHOD";
+    case AMQP_TX_SELECT_OK_METHOD: return "AMQP_TX_SELECT_OK_METHOD";
+    case AMQP_TX_COMMIT_METHOD: return "AMQP_TX_COMMIT_METHOD";
+    case AMQP_TX_COMMIT_OK_METHOD: return "AMQP_TX_COMMIT_OK_METHOD";
+    case AMQP_TX_ROLLBACK_METHOD: return "AMQP_TX_ROLLBACK_METHOD";
+    case AMQP_TX_ROLLBACK_OK_METHOD: return "AMQP_TX_ROLLBACK_OK_METHOD";
+    case AMQP_CONFIRM_SELECT_METHOD: return "AMQP_CONFIRM_SELECT_METHOD";
+    case AMQP_CONFIRM_SELECT_OK_METHOD: return "AMQP_CONFIRM_SELECT_OK_METHOD";
+    default: return NULL;
+  }
+}
+
+amqp_boolean_t amqp_method_has_content(amqp_method_number_t methodNumber) {
+  switch (methodNumber) {
+    case AMQP_BASIC_PUBLISH_METHOD: return 1;
+    case AMQP_BASIC_RETURN_METHOD: return 1;
+    case AMQP_BASIC_DELIVER_METHOD: return 1;
+    case AMQP_BASIC_GET_OK_METHOD: return 1;
+    default: return 0;
+  }
+}
+
+int amqp_decode_method(amqp_method_number_t methodNumber,
+                       amqp_pool_t *pool,
+                       amqp_bytes_t encoded,
+                       void **decoded)
+{
+  size_t offset = 0;
+  uint8_t bit_buffer;
+
+  switch (methodNumber) {
+    case AMQP_CONNECTION_START_METHOD: {
+      amqp_connection_start_t *m = (amqp_connection_start_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_start_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_8(encoded, &offset, &m->version_major)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &m->version_minor)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->server_properties), &offset);
+        if (res < 0) return res;
+      }
+      {
+        uint32_t len;
+        if (!amqp_decode_32(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->mechanisms, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint32_t len;
+        if (!amqp_decode_32(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->locales, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_START_OK_METHOD: {
+      amqp_connection_start_ok_t *m = (amqp_connection_start_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_start_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->client_properties), &offset);
+        if (res < 0) return res;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->mechanism, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint32_t len;
+        if (!amqp_decode_32(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->response, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->locale, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_SECURE_METHOD: {
+      amqp_connection_secure_t *m = (amqp_connection_secure_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_secure_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint32_t len;
+        if (!amqp_decode_32(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->challenge, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_SECURE_OK_METHOD: {
+      amqp_connection_secure_ok_t *m = (amqp_connection_secure_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_secure_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint32_t len;
+        if (!amqp_decode_32(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->response, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_TUNE_METHOD: {
+      amqp_connection_tune_t *m = (amqp_connection_tune_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_tune_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_32(encoded, &offset, &m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_16(encoded, &offset, &m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_TUNE_OK_METHOD: {
+      amqp_connection_tune_ok_t *m = (amqp_connection_tune_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_tune_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_32(encoded, &offset, &m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_16(encoded, &offset, &m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_OPEN_METHOD: {
+      amqp_connection_open_t *m = (amqp_connection_open_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_open_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->virtual_host, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->capabilities, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->insist = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_OPEN_OK_METHOD: {
+      amqp_connection_open_ok_t *m = (amqp_connection_open_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_open_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->known_hosts, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_CLOSE_METHOD: {
+      amqp_connection_close_t *m = (amqp_connection_close_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_close_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->reply_text, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_16(encoded, &offset, &m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_16(encoded, &offset, &m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_CLOSE_OK_METHOD: {
+      amqp_connection_close_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_BLOCKED_METHOD: {
+      amqp_connection_blocked_t *m = (amqp_connection_blocked_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_blocked_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->reason, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONNECTION_UNBLOCKED_METHOD: {
+      amqp_connection_unblocked_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CHANNEL_OPEN_METHOD: {
+      amqp_channel_open_t *m = (amqp_channel_open_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_open_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->out_of_band, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CHANNEL_OPEN_OK_METHOD: {
+      amqp_channel_open_ok_t *m = (amqp_channel_open_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_open_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint32_t len;
+        if (!amqp_decode_32(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->channel_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CHANNEL_FLOW_METHOD: {
+      amqp_channel_flow_t *m = (amqp_channel_flow_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_flow_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->active = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CHANNEL_FLOW_OK_METHOD: {
+      amqp_channel_flow_ok_t *m = (amqp_channel_flow_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_flow_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->active = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CHANNEL_CLOSE_METHOD: {
+      amqp_channel_close_t *m = (amqp_channel_close_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_close_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->reply_text, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_16(encoded, &offset, &m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_16(encoded, &offset, &m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CHANNEL_CLOSE_OK_METHOD: {
+      amqp_channel_close_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_ACCESS_REQUEST_METHOD: {
+      amqp_access_request_t *m = (amqp_access_request_t *) amqp_pool_alloc(pool, sizeof(amqp_access_request_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->realm, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->exclusive = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->passive = (bit_buffer & (1 << 1)) ? 1 : 0;
+      m->active = (bit_buffer & (1 << 2)) ? 1 : 0;
+      m->write = (bit_buffer & (1 << 3)) ? 1 : 0;
+      m->read = (bit_buffer & (1 << 4)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_ACCESS_REQUEST_OK_METHOD: {
+      amqp_access_request_ok_t *m = (amqp_access_request_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_access_request_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_DECLARE_METHOD: {
+      amqp_exchange_declare_t *m = (amqp_exchange_declare_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_declare_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->type, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->passive = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->durable = (bit_buffer & (1 << 1)) ? 1 : 0;
+      m->auto_delete = (bit_buffer & (1 << 2)) ? 1 : 0;
+      m->internal = (bit_buffer & (1 << 3)) ? 1 : 0;
+      m->nowait = (bit_buffer & (1 << 4)) ? 1 : 0;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_DECLARE_OK_METHOD: {
+      amqp_exchange_declare_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_DELETE_METHOD: {
+      amqp_exchange_delete_t *m = (amqp_exchange_delete_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_delete_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->if_unused = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->nowait = (bit_buffer & (1 << 1)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_DELETE_OK_METHOD: {
+      amqp_exchange_delete_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_BIND_METHOD: {
+      amqp_exchange_bind_t *m = (amqp_exchange_bind_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_bind_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->destination, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->source, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_BIND_OK_METHOD: {
+      amqp_exchange_bind_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_UNBIND_METHOD: {
+      amqp_exchange_unbind_t *m = (amqp_exchange_unbind_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_unbind_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->destination, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->source, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_EXCHANGE_UNBIND_OK_METHOD: {
+      amqp_exchange_unbind_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_DECLARE_METHOD: {
+      amqp_queue_declare_t *m = (amqp_queue_declare_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_declare_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->passive = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->durable = (bit_buffer & (1 << 1)) ? 1 : 0;
+      m->exclusive = (bit_buffer & (1 << 2)) ? 1 : 0;
+      m->auto_delete = (bit_buffer & (1 << 3)) ? 1 : 0;
+      m->nowait = (bit_buffer & (1 << 4)) ? 1 : 0;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_DECLARE_OK_METHOD: {
+      amqp_queue_declare_ok_t *m = (amqp_queue_declare_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_declare_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_32(encoded, &offset, &m->consumer_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_BIND_METHOD: {
+      amqp_queue_bind_t *m = (amqp_queue_bind_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_bind_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_BIND_OK_METHOD: {
+      amqp_queue_bind_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_PURGE_METHOD: {
+      amqp_queue_purge_t *m = (amqp_queue_purge_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_purge_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_PURGE_OK_METHOD: {
+      amqp_queue_purge_ok_t *m = (amqp_queue_purge_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_purge_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_DELETE_METHOD: {
+      amqp_queue_delete_t *m = (amqp_queue_delete_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_delete_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->if_unused = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->if_empty = (bit_buffer & (1 << 1)) ? 1 : 0;
+      m->nowait = (bit_buffer & (1 << 2)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_DELETE_OK_METHOD: {
+      amqp_queue_delete_ok_t *m = (amqp_queue_delete_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_delete_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_UNBIND_METHOD: {
+      amqp_queue_unbind_t *m = (amqp_queue_unbind_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_unbind_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_QUEUE_UNBIND_OK_METHOD: {
+      amqp_queue_unbind_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_QOS_METHOD: {
+      amqp_basic_qos_t *m = (amqp_basic_qos_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_qos_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_32(encoded, &offset, &m->prefetch_size)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_16(encoded, &offset, &m->prefetch_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->global = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_QOS_OK_METHOD: {
+      amqp_basic_qos_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_CONSUME_METHOD: {
+      amqp_basic_consume_t *m = (amqp_basic_consume_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_consume_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->no_local = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->no_ack = (bit_buffer & (1 << 1)) ? 1 : 0;
+      m->exclusive = (bit_buffer & (1 << 2)) ? 1 : 0;
+      m->nowait = (bit_buffer & (1 << 3)) ? 1 : 0;
+      {
+        int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_CONSUME_OK_METHOD: {
+      amqp_basic_consume_ok_t *m = (amqp_basic_consume_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_consume_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_CANCEL_METHOD: {
+      amqp_basic_cancel_t *m = (amqp_basic_cancel_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_cancel_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_CANCEL_OK_METHOD: {
+      amqp_basic_cancel_ok_t *m = (amqp_basic_cancel_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_cancel_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_PUBLISH_METHOD: {
+      amqp_basic_publish_t *m = (amqp_basic_publish_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_publish_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->mandatory = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->immediate = (bit_buffer & (1 << 1)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_RETURN_METHOD: {
+      amqp_basic_return_t *m = (amqp_basic_return_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_return_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->reply_text, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_DELIVER_METHOD: {
+      amqp_basic_deliver_t *m = (amqp_basic_deliver_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_deliver_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->redelivered = (bit_buffer & (1 << 0)) ? 1 : 0;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_GET_METHOD: {
+      amqp_basic_get_t *m = (amqp_basic_get_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_get_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_16(encoded, &offset, &m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->queue, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->no_ack = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_GET_OK_METHOD: {
+      amqp_basic_get_ok_t *m = (amqp_basic_get_ok_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_get_ok_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->redelivered = (bit_buffer & (1 << 0)) ? 1 : 0;
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->exchange, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->routing_key, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (!amqp_decode_32(encoded, &offset, &m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_GET_EMPTY_METHOD: {
+      amqp_basic_get_empty_t *m = (amqp_basic_get_empty_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_get_empty_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &m->cluster_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_ACK_METHOD: {
+      amqp_basic_ack_t *m = (amqp_basic_ack_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_ack_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->multiple = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_REJECT_METHOD: {
+      amqp_basic_reject_t *m = (amqp_basic_reject_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_reject_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_RECOVER_ASYNC_METHOD: {
+      amqp_basic_recover_async_t *m = (amqp_basic_recover_async_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_recover_async_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_RECOVER_METHOD: {
+      amqp_basic_recover_t *m = (amqp_basic_recover_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_recover_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_RECOVER_OK_METHOD: {
+      amqp_basic_recover_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_BASIC_NACK_METHOD: {
+      amqp_basic_nack_t *m = (amqp_basic_nack_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_nack_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->multiple = (bit_buffer & (1 << 0)) ? 1 : 0;
+      m->requeue = (bit_buffer & (1 << 1)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_TX_SELECT_METHOD: {
+      amqp_tx_select_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_TX_SELECT_OK_METHOD: {
+      amqp_tx_select_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_TX_COMMIT_METHOD: {
+      amqp_tx_commit_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_TX_COMMIT_OK_METHOD: {
+      amqp_tx_commit_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_TX_ROLLBACK_METHOD: {
+      amqp_tx_rollback_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_TX_ROLLBACK_OK_METHOD: {
+      amqp_tx_rollback_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONFIRM_SELECT_METHOD: {
+      amqp_confirm_select_t *m = (amqp_confirm_select_t *) amqp_pool_alloc(pool, sizeof(amqp_confirm_select_t));
+      if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0;
+      *decoded = m;
+      return 0;
+    }
+    case AMQP_CONFIRM_SELECT_OK_METHOD: {
+      amqp_confirm_select_ok_t *m = NULL; /* no fields */
+      *decoded = m;
+      return 0;
+    }
+    default: return AMQP_STATUS_UNKNOWN_METHOD;
+  }
+}
+
+int amqp_decode_properties(uint16_t class_id,
+                           amqp_pool_t *pool,
+                           amqp_bytes_t encoded,
+                           void **decoded)
+{
+  size_t offset = 0;
+
+  amqp_flags_t flags = 0;
+  int flagword_index = 0;
+  uint16_t partial_flags;
+
+  do {
+    if (!amqp_decode_16(encoded, &offset, &partial_flags))
+      return AMQP_STATUS_BAD_AMQP_DATA;
+    flags |= (partial_flags << (flagword_index * 16));
+    flagword_index++;
+  } while (partial_flags & 1);
+
+  switch (class_id) {
+    case 10: {
+      amqp_connection_properties_t *p = (amqp_connection_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_connection_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    case 20: {
+      amqp_channel_properties_t *p = (amqp_channel_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_channel_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    case 30: {
+      amqp_access_properties_t *p = (amqp_access_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_access_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    case 40: {
+      amqp_exchange_properties_t *p = (amqp_exchange_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_exchange_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    case 50: {
+      amqp_queue_properties_t *p = (amqp_queue_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_queue_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    case 60: {
+      amqp_basic_properties_t *p = (amqp_basic_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_basic_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      if (flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->content_type, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->content_encoding, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_HEADERS_FLAG) {
+      {
+        int res = amqp_decode_table(encoded, pool, &(p->headers), &offset);
+        if (res < 0) return res;
+      }
+      }
+      if (flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
+      if (!amqp_decode_8(encoded, &offset, &p->delivery_mode)) return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (flags & AMQP_BASIC_PRIORITY_FLAG) {
+      if (!amqp_decode_8(encoded, &offset, &p->priority)) return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->correlation_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_REPLY_TO_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->reply_to, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_EXPIRATION_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->expiration, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_MESSAGE_ID_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->message_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_TIMESTAMP_FLAG) {
+      if (!amqp_decode_64(encoded, &offset, &p->timestamp)) return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      if (flags & AMQP_BASIC_TYPE_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->type, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_USER_ID_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->user_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_APP_ID_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->app_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      if (flags & AMQP_BASIC_CLUSTER_ID_FLAG) {
+      {
+        uint8_t len;
+        if (!amqp_decode_8(encoded, &offset, &len)
+            || !amqp_decode_bytes(encoded, &offset, &p->cluster_id, len))
+          return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      }
+      *decoded = p;
+      return 0;
+    }
+    case 90: {
+      amqp_tx_properties_t *p = (amqp_tx_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_tx_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    case 85: {
+      amqp_confirm_properties_t *p = (amqp_confirm_properties_t *) amqp_pool_alloc(pool, sizeof(amqp_confirm_properties_t));
+      if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }
+      p->_flags = flags;
+      *decoded = p;
+      return 0;
+    }
+    default: return AMQP_STATUS_UNKNOWN_CLASS;
+  }
+}
+
+int amqp_encode_method(amqp_method_number_t methodNumber,
+                       void *decoded,
+                       amqp_bytes_t encoded)
+{
+  size_t offset = 0;
+  uint8_t bit_buffer;
+
+  switch (methodNumber) {
+    case AMQP_CONNECTION_START_METHOD: {
+      amqp_connection_start_t *m = (amqp_connection_start_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->version_major)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->version_minor)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->server_properties), &offset);
+        if (res < 0) return res;
+      }
+      if (!amqp_encode_32(encoded, &offset, m->mechanisms.len)
+          || !amqp_encode_bytes(encoded, &offset, m->mechanisms))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->locales.len)
+          || !amqp_encode_bytes(encoded, &offset, m->locales))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_START_OK_METHOD: {
+      amqp_connection_start_ok_t *m = (amqp_connection_start_ok_t *) decoded;
+      {
+        int res = amqp_encode_table(encoded, &(m->client_properties), &offset);
+        if (res < 0) return res;
+      }
+      if (!amqp_encode_8(encoded, &offset, m->mechanism.len)
+          || !amqp_encode_bytes(encoded, &offset, m->mechanism))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->response.len)
+          || !amqp_encode_bytes(encoded, &offset, m->response))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->locale.len)
+          || !amqp_encode_bytes(encoded, &offset, m->locale))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_SECURE_METHOD: {
+      amqp_connection_secure_t *m = (amqp_connection_secure_t *) decoded;
+      if (!amqp_encode_32(encoded, &offset, m->challenge.len)
+          || !amqp_encode_bytes(encoded, &offset, m->challenge))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_SECURE_OK_METHOD: {
+      amqp_connection_secure_ok_t *m = (amqp_connection_secure_ok_t *) decoded;
+      if (!amqp_encode_32(encoded, &offset, m->response.len)
+          || !amqp_encode_bytes(encoded, &offset, m->response))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_TUNE_METHOD: {
+      amqp_connection_tune_t *m = (amqp_connection_tune_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_TUNE_OK_METHOD: {
+      amqp_connection_tune_ok_t *m = (amqp_connection_tune_ok_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->channel_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->frame_max)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->heartbeat)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_OPEN_METHOD: {
+      amqp_connection_open_t *m = (amqp_connection_open_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->virtual_host.len)
+          || !amqp_encode_bytes(encoded, &offset, m->virtual_host))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->capabilities.len)
+          || !amqp_encode_bytes(encoded, &offset, m->capabilities))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->insist) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_OPEN_OK_METHOD: {
+      amqp_connection_open_ok_t *m = (amqp_connection_open_ok_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->known_hosts.len)
+          || !amqp_encode_bytes(encoded, &offset, m->known_hosts))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_CLOSE_METHOD: {
+      amqp_connection_close_t *m = (amqp_connection_close_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->reply_text.len)
+          || !amqp_encode_bytes(encoded, &offset, m->reply_text))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_CLOSE_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_CONNECTION_BLOCKED_METHOD: {
+      amqp_connection_blocked_t *m = (amqp_connection_blocked_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->reason.len)
+          || !amqp_encode_bytes(encoded, &offset, m->reason))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONNECTION_UNBLOCKED_METHOD: {
+      return offset;
+    }
+    case AMQP_CHANNEL_OPEN_METHOD: {
+      amqp_channel_open_t *m = (amqp_channel_open_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->out_of_band.len)
+          || !amqp_encode_bytes(encoded, &offset, m->out_of_band))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CHANNEL_OPEN_OK_METHOD: {
+      amqp_channel_open_ok_t *m = (amqp_channel_open_ok_t *) decoded;
+      if (!amqp_encode_32(encoded, &offset, m->channel_id.len)
+          || !amqp_encode_bytes(encoded, &offset, m->channel_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CHANNEL_FLOW_METHOD: {
+      amqp_channel_flow_t *m = (amqp_channel_flow_t *) decoded;
+      bit_buffer = 0;
+      if (m->active) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CHANNEL_FLOW_OK_METHOD: {
+      amqp_channel_flow_ok_t *m = (amqp_channel_flow_ok_t *) decoded;
+      bit_buffer = 0;
+      if (m->active) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CHANNEL_CLOSE_METHOD: {
+      amqp_channel_close_t *m = (amqp_channel_close_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->reply_text.len)
+          || !amqp_encode_bytes(encoded, &offset, m->reply_text))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->class_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->method_id)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CHANNEL_CLOSE_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_ACCESS_REQUEST_METHOD: {
+      amqp_access_request_t *m = (amqp_access_request_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->realm.len)
+          || !amqp_encode_bytes(encoded, &offset, m->realm))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->exclusive) bit_buffer |= (1 << 0);
+      if (m->passive) bit_buffer |= (1 << 1);
+      if (m->active) bit_buffer |= (1 << 2);
+      if (m->write) bit_buffer |= (1 << 3);
+      if (m->read) bit_buffer |= (1 << 4);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_ACCESS_REQUEST_OK_METHOD: {
+      amqp_access_request_ok_t *m = (amqp_access_request_ok_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_EXCHANGE_DECLARE_METHOD: {
+      amqp_exchange_declare_t *m = (amqp_exchange_declare_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->type.len)
+          || !amqp_encode_bytes(encoded, &offset, m->type))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->passive) bit_buffer |= (1 << 0);
+      if (m->durable) bit_buffer |= (1 << 1);
+      if (m->auto_delete) bit_buffer |= (1 << 2);
+      if (m->internal) bit_buffer |= (1 << 3);
+      if (m->nowait) bit_buffer |= (1 << 4);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_EXCHANGE_DECLARE_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_EXCHANGE_DELETE_METHOD: {
+      amqp_exchange_delete_t *m = (amqp_exchange_delete_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->if_unused) bit_buffer |= (1 << 0);
+      if (m->nowait) bit_buffer |= (1 << 1);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_EXCHANGE_DELETE_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_EXCHANGE_BIND_METHOD: {
+      amqp_exchange_bind_t *m = (amqp_exchange_bind_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->destination.len)
+          || !amqp_encode_bytes(encoded, &offset, m->destination))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->source.len)
+          || !amqp_encode_bytes(encoded, &offset, m->source))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->nowait) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_EXCHANGE_BIND_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_EXCHANGE_UNBIND_METHOD: {
+      amqp_exchange_unbind_t *m = (amqp_exchange_unbind_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->destination.len)
+          || !amqp_encode_bytes(encoded, &offset, m->destination))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->source.len)
+          || !amqp_encode_bytes(encoded, &offset, m->source))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->nowait) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_EXCHANGE_UNBIND_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_QUEUE_DECLARE_METHOD: {
+      amqp_queue_declare_t *m = (amqp_queue_declare_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->passive) bit_buffer |= (1 << 0);
+      if (m->durable) bit_buffer |= (1 << 1);
+      if (m->exclusive) bit_buffer |= (1 << 2);
+      if (m->auto_delete) bit_buffer |= (1 << 3);
+      if (m->nowait) bit_buffer |= (1 << 4);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_QUEUE_DECLARE_OK_METHOD: {
+      amqp_queue_declare_ok_t *m = (amqp_queue_declare_ok_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->consumer_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_QUEUE_BIND_METHOD: {
+      amqp_queue_bind_t *m = (amqp_queue_bind_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->nowait) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_QUEUE_BIND_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_QUEUE_PURGE_METHOD: {
+      amqp_queue_purge_t *m = (amqp_queue_purge_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->nowait) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_QUEUE_PURGE_OK_METHOD: {
+      amqp_queue_purge_ok_t *m = (amqp_queue_purge_ok_t *) decoded;
+      if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_QUEUE_DELETE_METHOD: {
+      amqp_queue_delete_t *m = (amqp_queue_delete_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->if_unused) bit_buffer |= (1 << 0);
+      if (m->if_empty) bit_buffer |= (1 << 1);
+      if (m->nowait) bit_buffer |= (1 << 2);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_QUEUE_DELETE_OK_METHOD: {
+      amqp_queue_delete_ok_t *m = (amqp_queue_delete_ok_t *) decoded;
+      if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_QUEUE_UNBIND_METHOD: {
+      amqp_queue_unbind_t *m = (amqp_queue_unbind_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_QUEUE_UNBIND_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_BASIC_QOS_METHOD: {
+      amqp_basic_qos_t *m = (amqp_basic_qos_t *) decoded;
+      if (!amqp_encode_32(encoded, &offset, m->prefetch_size)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_16(encoded, &offset, m->prefetch_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->global) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_QOS_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_BASIC_CONSUME_METHOD: {
+      amqp_basic_consume_t *m = (amqp_basic_consume_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->consumer_tag.len)
+          || !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->no_local) bit_buffer |= (1 << 0);
+      if (m->no_ack) bit_buffer |= (1 << 1);
+      if (m->exclusive) bit_buffer |= (1 << 2);
+      if (m->nowait) bit_buffer |= (1 << 3);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      {
+        int res = amqp_encode_table(encoded, &(m->arguments), &offset);
+        if (res < 0) return res;
+      }
+      return offset;
+    }
+    case AMQP_BASIC_CONSUME_OK_METHOD: {
+      amqp_basic_consume_ok_t *m = (amqp_basic_consume_ok_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->consumer_tag.len)
+          || !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_CANCEL_METHOD: {
+      amqp_basic_cancel_t *m = (amqp_basic_cancel_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->consumer_tag.len)
+          || !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->nowait) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_CANCEL_OK_METHOD: {
+      amqp_basic_cancel_ok_t *m = (amqp_basic_cancel_ok_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->consumer_tag.len)
+          || !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_PUBLISH_METHOD: {
+      amqp_basic_publish_t *m = (amqp_basic_publish_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->mandatory) bit_buffer |= (1 << 0);
+      if (m->immediate) bit_buffer |= (1 << 1);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_RETURN_METHOD: {
+      amqp_basic_return_t *m = (amqp_basic_return_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->reply_code)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->reply_text.len)
+          || !amqp_encode_bytes(encoded, &offset, m->reply_text))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_DELIVER_METHOD: {
+      amqp_basic_deliver_t *m = (amqp_basic_deliver_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->consumer_tag.len)
+          || !amqp_encode_bytes(encoded, &offset, m->consumer_tag))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->redelivered) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_GET_METHOD: {
+      amqp_basic_get_t *m = (amqp_basic_get_t *) decoded;
+      if (!amqp_encode_16(encoded, &offset, m->ticket)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->queue.len)
+          || !amqp_encode_bytes(encoded, &offset, m->queue))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->no_ack) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_GET_OK_METHOD: {
+      amqp_basic_get_ok_t *m = (amqp_basic_get_ok_t *) decoded;
+      if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->redelivered) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->exchange.len)
+          || !amqp_encode_bytes(encoded, &offset, m->exchange))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_8(encoded, &offset, m->routing_key.len)
+          || !amqp_encode_bytes(encoded, &offset, m->routing_key))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      if (!amqp_encode_32(encoded, &offset, m->message_count)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_GET_EMPTY_METHOD: {
+      amqp_basic_get_empty_t *m = (amqp_basic_get_empty_t *) decoded;
+      if (!amqp_encode_8(encoded, &offset, m->cluster_id.len)
+          || !amqp_encode_bytes(encoded, &offset, m->cluster_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_ACK_METHOD: {
+      amqp_basic_ack_t *m = (amqp_basic_ack_t *) decoded;
+      if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->multiple) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_REJECT_METHOD: {
+      amqp_basic_reject_t *m = (amqp_basic_reject_t *) decoded;
+      if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->requeue) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_RECOVER_ASYNC_METHOD: {
+      amqp_basic_recover_async_t *m = (amqp_basic_recover_async_t *) decoded;
+      bit_buffer = 0;
+      if (m->requeue) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_RECOVER_METHOD: {
+      amqp_basic_recover_t *m = (amqp_basic_recover_t *) decoded;
+      bit_buffer = 0;
+      if (m->requeue) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_BASIC_RECOVER_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_BASIC_NACK_METHOD: {
+      amqp_basic_nack_t *m = (amqp_basic_nack_t *) decoded;
+      if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) return AMQP_STATUS_BAD_AMQP_DATA;
+      bit_buffer = 0;
+      if (m->multiple) bit_buffer |= (1 << 0);
+      if (m->requeue) bit_buffer |= (1 << 1);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_TX_SELECT_METHOD: {
+      return offset;
+    }
+    case AMQP_TX_SELECT_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_TX_COMMIT_METHOD: {
+      return offset;
+    }
+    case AMQP_TX_COMMIT_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_TX_ROLLBACK_METHOD: {
+      return offset;
+    }
+    case AMQP_TX_ROLLBACK_OK_METHOD: {
+      return offset;
+    }
+    case AMQP_CONFIRM_SELECT_METHOD: {
+      amqp_confirm_select_t *m = (amqp_confirm_select_t *) decoded;
+      bit_buffer = 0;
+      if (m->nowait) bit_buffer |= (1 << 0);
+      if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;
+      return offset;
+    }
+    case AMQP_CONFIRM_SELECT_OK_METHOD: {
+      return offset;
+    }
+    default: return AMQP_STATUS_UNKNOWN_METHOD;
+  }
+}
+
+int amqp_encode_properties(uint16_t class_id,
+                           void *decoded,
+                           amqp_bytes_t encoded)
+{
+  size_t offset = 0;
+
+  /* Cheat, and get the flags out generically, relying on the
+     similarity of structure between classes */
+  amqp_flags_t flags = * (amqp_flags_t *) decoded; /* cheating! */
+
+  {
+    /* We take a copy of flags to avoid destroying it, as it is used
+       in the autogenerated code below. */
+    amqp_flags_t remaining_flags = flags;
+    do {
+      amqp_flags_t remainder = remaining_flags >> 16;
+      uint16_t partial_flags = remaining_flags & 0xFFFE;
+      if (remainder != 0) { partial_flags |= 1; }
+      if (!amqp_encode_16(encoded, &offset, partial_flags))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      remaining_flags = remainder;
+    } while (remaining_flags != 0);
+  }
+
+  switch (class_id) {
+    case 10: {
+      return offset;
+    }
+    case 20: {
+      return offset;
+    }
+    case 30: {
+      return offset;
+    }
+    case 40: {
+      return offset;
+    }
+    case 50: {
+      return offset;
+    }
+    case 60: {
+      amqp_basic_properties_t *p = (amqp_basic_properties_t *) decoded;
+            if (flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->content_type.len)
+          || !amqp_encode_bytes(encoded, &offset, p->content_type))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->content_encoding.len)
+          || !amqp_encode_bytes(encoded, &offset, p->content_encoding))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_HEADERS_FLAG) {
+      {
+        int res = amqp_encode_table(encoded, &(p->headers), &offset);
+        if (res < 0) return res;
+      }
+      }
+            if (flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->delivery_mode)) return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_PRIORITY_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->priority)) return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->correlation_id.len)
+          || !amqp_encode_bytes(encoded, &offset, p->correlation_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_REPLY_TO_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->reply_to.len)
+          || !amqp_encode_bytes(encoded, &offset, p->reply_to))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_EXPIRATION_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->expiration.len)
+          || !amqp_encode_bytes(encoded, &offset, p->expiration))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_MESSAGE_ID_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->message_id.len)
+          || !amqp_encode_bytes(encoded, &offset, p->message_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_TIMESTAMP_FLAG) {
+      if (!amqp_encode_64(encoded, &offset, p->timestamp)) return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_TYPE_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->type.len)
+          || !amqp_encode_bytes(encoded, &offset, p->type))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_USER_ID_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->user_id.len)
+          || !amqp_encode_bytes(encoded, &offset, p->user_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_APP_ID_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->app_id.len)
+          || !amqp_encode_bytes(encoded, &offset, p->app_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+            if (flags & AMQP_BASIC_CLUSTER_ID_FLAG) {
+      if (!amqp_encode_8(encoded, &offset, p->cluster_id.len)
+          || !amqp_encode_bytes(encoded, &offset, p->cluster_id))
+        return AMQP_STATUS_BAD_AMQP_DATA;
+      }
+      return offset;
+    }
+    case 90: {
+      return offset;
+    }
+    case 85: {
+      return offset;
+    }
+    default: return AMQP_STATUS_UNKNOWN_CLASS;
+  }
+}
+
+AMQP_PUBLIC_FUNCTION amqp_channel_open_ok_t * AMQP_CALL amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_channel_open_t req;
+  req.out_of_band = amqp_empty_bytes;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_CHANNEL_OPEN_METHOD, AMQP_CHANNEL_OPEN_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_channel_flow_ok_t * AMQP_CALL amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t active)
+{
+  amqp_channel_flow_t req;
+  req.active = active;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_CHANNEL_FLOW_METHOD, AMQP_CHANNEL_FLOW_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_exchange_declare_ok_t * AMQP_CALL amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable, amqp_table_t arguments)
+{
+  amqp_exchange_declare_t req;
+  req.ticket = 0;
+  req.exchange = exchange;
+  req.type = type;
+  req.passive = passive;
+  req.durable = durable;
+  req.auto_delete = 0;
+  req.internal = 0;
+  req.nowait = 0;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_DECLARE_METHOD, AMQP_EXCHANGE_DECLARE_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_exchange_delete_ok_t * AMQP_CALL amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_boolean_t if_unused)
+{
+  amqp_exchange_delete_t req;
+  req.ticket = 0;
+  req.exchange = exchange;
+  req.if_unused = if_unused;
+  req.nowait = 0;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_DELETE_METHOD, AMQP_EXCHANGE_DELETE_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_exchange_bind_ok_t * AMQP_CALL amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments)
+{
+  amqp_exchange_bind_t req;
+  req.ticket = 0;
+  req.destination = destination;
+  req.source = source;
+  req.routing_key = routing_key;
+  req.nowait = 0;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_BIND_METHOD, AMQP_EXCHANGE_BIND_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_exchange_unbind_ok_t * AMQP_CALL amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments)
+{
+  amqp_exchange_unbind_t req;
+  req.ticket = 0;
+  req.destination = destination;
+  req.source = source;
+  req.routing_key = routing_key;
+  req.nowait = 0;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_UNBIND_METHOD, AMQP_EXCHANGE_UNBIND_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_queue_declare_ok_t * AMQP_CALL amqp_queue_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, amqp_boolean_t auto_delete, amqp_table_t arguments)
+{
+  amqp_queue_declare_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.passive = passive;
+  req.durable = durable;
+  req.exclusive = exclusive;
+  req.auto_delete = auto_delete;
+  req.nowait = 0;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_DECLARE_METHOD, AMQP_QUEUE_DECLARE_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_queue_bind_ok_t * AMQP_CALL amqp_queue_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments)
+{
+  amqp_queue_bind_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.exchange = exchange;
+  req.routing_key = routing_key;
+  req.nowait = 0;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_BIND_METHOD, AMQP_QUEUE_BIND_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_queue_purge_ok_t * AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue)
+{
+  amqp_queue_purge_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.nowait = 0;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_PURGE_METHOD, AMQP_QUEUE_PURGE_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_queue_delete_ok_t * AMQP_CALL amqp_queue_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t if_unused, amqp_boolean_t if_empty)
+{
+  amqp_queue_delete_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.if_unused = if_unused;
+  req.if_empty = if_empty;
+  req.nowait = 0;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_DELETE_METHOD, AMQP_QUEUE_DELETE_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_queue_unbind_ok_t * AMQP_CALL amqp_queue_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments)
+{
+  amqp_queue_unbind_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.exchange = exchange;
+  req.routing_key = routing_key;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_UNBIND_METHOD, AMQP_QUEUE_UNBIND_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_basic_qos_ok_t * AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, amqp_channel_t channel, uint32_t prefetch_size, uint16_t prefetch_count, amqp_boolean_t global)
+{
+  amqp_basic_qos_t req;
+  req.prefetch_size = prefetch_size;
+  req.prefetch_count = prefetch_count;
+  req.global = global;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_QOS_METHOD, AMQP_BASIC_QOS_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_basic_consume_ok_t * AMQP_CALL amqp_basic_consume(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, amqp_boolean_t exclusive, amqp_table_t arguments)
+{
+  amqp_basic_consume_t req;
+  req.ticket = 0;
+  req.queue = queue;
+  req.consumer_tag = consumer_tag;
+  req.no_local = no_local;
+  req.no_ack = no_ack;
+  req.exclusive = exclusive;
+  req.nowait = 0;
+  req.arguments = arguments;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_CONSUME_METHOD, AMQP_BASIC_CONSUME_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_basic_cancel_ok_t * AMQP_CALL amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t consumer_tag)
+{
+  amqp_basic_cancel_t req;
+  req.consumer_tag = consumer_tag;
+  req.nowait = 0;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_CANCEL_METHOD, AMQP_BASIC_CANCEL_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_basic_recover_ok_t * AMQP_CALL amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t requeue)
+{
+  amqp_basic_recover_t req;
+  req.requeue = requeue;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_RECOVER_METHOD, AMQP_BASIC_RECOVER_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_tx_select_ok_t * AMQP_CALL amqp_tx_select(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_tx_select_t req;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_TX_SELECT_METHOD, AMQP_TX_SELECT_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_tx_commit_ok_t * AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_tx_commit_t req;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_TX_COMMIT_METHOD, AMQP_TX_COMMIT_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_tx_rollback_ok_t * AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_tx_rollback_t req;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_TX_ROLLBACK_METHOD, AMQP_TX_ROLLBACK_OK_METHOD, &req);
+}
+
+
+AMQP_PUBLIC_FUNCTION amqp_confirm_select_ok_t * AMQP_CALL amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_confirm_select_t req;
+  req.nowait = 0;
+
+  return amqp_simple_rpc_decoded(state, channel, AMQP_CONFIRM_SELECT_METHOD, AMQP_CONFIRM_SELECT_OK_METHOD, &req);
+}
+
diff --git a/modules/kazoo/deps/amqp_framing.h b/modules/kazoo/deps/amqp_framing.h
new file mode 100644
index 0000000..0c04cb8
--- /dev/null
+++ b/modules/kazoo/deps/amqp_framing.h
@@ -0,0 +1,640 @@
+/* Generated code. Do not edit. Edit and re-run codegen.py instead.
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2013
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifndef AMQP_FRAMING_H
+#define AMQP_FRAMING_H
+
+#include <amqp.h>
+
+AMQP_BEGIN_DECLS
+
+#define AMQP_PROTOCOL_VERSION_MAJOR 0
+#define AMQP_PROTOCOL_VERSION_MINOR 9
+#define AMQP_PROTOCOL_VERSION_REVISION 1
+#define AMQP_PROTOCOL_PORT 5672
+#define AMQP_FRAME_METHOD 1
+#define AMQP_FRAME_HEADER 2
+#define AMQP_FRAME_BODY 3
+#define AMQP_FRAME_HEARTBEAT 8
+#define AMQP_FRAME_MIN_SIZE 4096
+#define AMQP_FRAME_END 206
+#define AMQP_REPLY_SUCCESS 200
+#define AMQP_CONTENT_TOO_LARGE 311
+#define AMQP_NO_ROUTE 312
+#define AMQP_NO_CONSUMERS 313
+#define AMQP_ACCESS_REFUSED 403
+#define AMQP_NOT_FOUND 404
+#define AMQP_RESOURCE_LOCKED 405
+#define AMQP_PRECONDITION_FAILED 406
+#define AMQP_CONNECTION_FORCED 320
+#define AMQP_INVALID_PATH 402
+#define AMQP_FRAME_ERROR 501
+#define AMQP_SYNTAX_ERROR 502
+#define AMQP_COMMAND_INVALID 503
+#define AMQP_CHANNEL_ERROR 504
+#define AMQP_UNEXPECTED_FRAME 505
+#define AMQP_RESOURCE_ERROR 506
+#define AMQP_NOT_ALLOWED 530
+#define AMQP_NOT_IMPLEMENTED 540
+#define AMQP_INTERNAL_ERROR 541
+
+/* Function prototypes. */
+
+AMQP_PUBLIC_FUNCTION
+char const *
+AMQP_CALL amqp_constant_name(int constantNumber);
+
+AMQP_PUBLIC_FUNCTION
+amqp_boolean_t
+AMQP_CALL amqp_constant_is_hard_error(int constantNumber);
+
+AMQP_PUBLIC_FUNCTION
+char const *
+AMQP_CALL amqp_method_name(amqp_method_number_t methodNumber);
+
+AMQP_PUBLIC_FUNCTION
+amqp_boolean_t
+AMQP_CALL amqp_method_has_content(amqp_method_number_t methodNumber);
+
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_decode_method(amqp_method_number_t methodNumber,
+		   amqp_pool_t *pool,
+		   amqp_bytes_t encoded,
+		   void **decoded);
+
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_decode_properties(uint16_t class_id,
+            amqp_pool_t *pool,
+            amqp_bytes_t encoded,
+            void **decoded);
+
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_encode_method(amqp_method_number_t methodNumber,
+		   void *decoded,
+		   amqp_bytes_t encoded);
+
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL amqp_encode_properties(uint16_t class_id,
+		       void *decoded,
+		       amqp_bytes_t encoded);
+
+/* Method field records. */
+
+#define AMQP_CONNECTION_START_METHOD ((amqp_method_number_t) 0x000A000A) /* 10, 10; 655370 */
+typedef struct amqp_connection_start_t_ {
+  uint8_t version_major;
+  uint8_t version_minor;
+  amqp_table_t server_properties;
+  amqp_bytes_t mechanisms;
+  amqp_bytes_t locales;
+} amqp_connection_start_t;
+
+#define AMQP_CONNECTION_START_OK_METHOD ((amqp_method_number_t) 0x000A000B) /* 10, 11; 655371 */
+typedef struct amqp_connection_start_ok_t_ {
+  amqp_table_t client_properties;
+  amqp_bytes_t mechanism;
+  amqp_bytes_t response;
+  amqp_bytes_t locale;
+} amqp_connection_start_ok_t;
+
+#define AMQP_CONNECTION_SECURE_METHOD ((amqp_method_number_t) 0x000A0014) /* 10, 20; 655380 */
+typedef struct amqp_connection_secure_t_ {
+  amqp_bytes_t challenge;
+} amqp_connection_secure_t;
+
+#define AMQP_CONNECTION_SECURE_OK_METHOD ((amqp_method_number_t) 0x000A0015) /* 10, 21; 655381 */
+typedef struct amqp_connection_secure_ok_t_ {
+  amqp_bytes_t response;
+} amqp_connection_secure_ok_t;
+
+#define AMQP_CONNECTION_TUNE_METHOD ((amqp_method_number_t) 0x000A001E) /* 10, 30; 655390 */
+typedef struct amqp_connection_tune_t_ {
+  uint16_t channel_max;
+  uint32_t frame_max;
+  uint16_t heartbeat;
+} amqp_connection_tune_t;
+
+#define AMQP_CONNECTION_TUNE_OK_METHOD ((amqp_method_number_t) 0x000A001F) /* 10, 31; 655391 */
+typedef struct amqp_connection_tune_ok_t_ {
+  uint16_t channel_max;
+  uint32_t frame_max;
+  uint16_t heartbeat;
+} amqp_connection_tune_ok_t;
+
+#define AMQP_CONNECTION_OPEN_METHOD ((amqp_method_number_t) 0x000A0028) /* 10, 40; 655400 */
+typedef struct amqp_connection_open_t_ {
+  amqp_bytes_t virtual_host;
+  amqp_bytes_t capabilities;
+  amqp_boolean_t insist;
+} amqp_connection_open_t;
+
+#define AMQP_CONNECTION_OPEN_OK_METHOD ((amqp_method_number_t) 0x000A0029) /* 10, 41; 655401 */
+typedef struct amqp_connection_open_ok_t_ {
+  amqp_bytes_t known_hosts;
+} amqp_connection_open_ok_t;
+
+#define AMQP_CONNECTION_CLOSE_METHOD ((amqp_method_number_t) 0x000A0032) /* 10, 50; 655410 */
+typedef struct amqp_connection_close_t_ {
+  uint16_t reply_code;
+  amqp_bytes_t reply_text;
+  uint16_t class_id;
+  uint16_t method_id;
+} amqp_connection_close_t;
+
+#define AMQP_CONNECTION_CLOSE_OK_METHOD ((amqp_method_number_t) 0x000A0033) /* 10, 51; 655411 */
+typedef struct amqp_connection_close_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_connection_close_ok_t;
+
+#define AMQP_CONNECTION_BLOCKED_METHOD ((amqp_method_number_t) 0x000A003C) /* 10, 60; 655420 */
+typedef struct amqp_connection_blocked_t_ {
+  amqp_bytes_t reason;
+} amqp_connection_blocked_t;
+
+#define AMQP_CONNECTION_UNBLOCKED_METHOD ((amqp_method_number_t) 0x000A003D) /* 10, 61; 655421 */
+typedef struct amqp_connection_unblocked_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_connection_unblocked_t;
+
+#define AMQP_CHANNEL_OPEN_METHOD ((amqp_method_number_t) 0x0014000A) /* 20, 10; 1310730 */
+typedef struct amqp_channel_open_t_ {
+  amqp_bytes_t out_of_band;
+} amqp_channel_open_t;
+
+#define AMQP_CHANNEL_OPEN_OK_METHOD ((amqp_method_number_t) 0x0014000B) /* 20, 11; 1310731 */
+typedef struct amqp_channel_open_ok_t_ {
+  amqp_bytes_t channel_id;
+} amqp_channel_open_ok_t;
+
+#define AMQP_CHANNEL_FLOW_METHOD ((amqp_method_number_t) 0x00140014) /* 20, 20; 1310740 */
+typedef struct amqp_channel_flow_t_ {
+  amqp_boolean_t active;
+} amqp_channel_flow_t;
+
+#define AMQP_CHANNEL_FLOW_OK_METHOD ((amqp_method_number_t) 0x00140015) /* 20, 21; 1310741 */
+typedef struct amqp_channel_flow_ok_t_ {
+  amqp_boolean_t active;
+} amqp_channel_flow_ok_t;
+
+#define AMQP_CHANNEL_CLOSE_METHOD ((amqp_method_number_t) 0x00140028) /* 20, 40; 1310760 */
+typedef struct amqp_channel_close_t_ {
+  uint16_t reply_code;
+  amqp_bytes_t reply_text;
+  uint16_t class_id;
+  uint16_t method_id;
+} amqp_channel_close_t;
+
+#define AMQP_CHANNEL_CLOSE_OK_METHOD ((amqp_method_number_t) 0x00140029) /* 20, 41; 1310761 */
+typedef struct amqp_channel_close_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_channel_close_ok_t;
+
+#define AMQP_ACCESS_REQUEST_METHOD ((amqp_method_number_t) 0x001E000A) /* 30, 10; 1966090 */
+typedef struct amqp_access_request_t_ {
+  amqp_bytes_t realm;
+  amqp_boolean_t exclusive;
+  amqp_boolean_t passive;
+  amqp_boolean_t active;
+  amqp_boolean_t write;
+  amqp_boolean_t read;
+} amqp_access_request_t;
+
+#define AMQP_ACCESS_REQUEST_OK_METHOD ((amqp_method_number_t) 0x001E000B) /* 30, 11; 1966091 */
+typedef struct amqp_access_request_ok_t_ {
+  uint16_t ticket;
+} amqp_access_request_ok_t;
+
+#define AMQP_EXCHANGE_DECLARE_METHOD ((amqp_method_number_t) 0x0028000A) /* 40, 10; 2621450 */
+typedef struct amqp_exchange_declare_t_ {
+  uint16_t ticket;
+  amqp_bytes_t exchange;
+  amqp_bytes_t type;
+  amqp_boolean_t passive;
+  amqp_boolean_t durable;
+  amqp_boolean_t auto_delete;
+  amqp_boolean_t internal;
+  amqp_boolean_t nowait;
+  amqp_table_t arguments;
+} amqp_exchange_declare_t;
+
+#define AMQP_EXCHANGE_DECLARE_OK_METHOD ((amqp_method_number_t) 0x0028000B) /* 40, 11; 2621451 */
+typedef struct amqp_exchange_declare_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_exchange_declare_ok_t;
+
+#define AMQP_EXCHANGE_DELETE_METHOD ((amqp_method_number_t) 0x00280014) /* 40, 20; 2621460 */
+typedef struct amqp_exchange_delete_t_ {
+  uint16_t ticket;
+  amqp_bytes_t exchange;
+  amqp_boolean_t if_unused;
+  amqp_boolean_t nowait;
+} amqp_exchange_delete_t;
+
+#define AMQP_EXCHANGE_DELETE_OK_METHOD ((amqp_method_number_t) 0x00280015) /* 40, 21; 2621461 */
+typedef struct amqp_exchange_delete_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_exchange_delete_ok_t;
+
+#define AMQP_EXCHANGE_BIND_METHOD ((amqp_method_number_t) 0x0028001E) /* 40, 30; 2621470 */
+typedef struct amqp_exchange_bind_t_ {
+  uint16_t ticket;
+  amqp_bytes_t destination;
+  amqp_bytes_t source;
+  amqp_bytes_t routing_key;
+  amqp_boolean_t nowait;
+  amqp_table_t arguments;
+} amqp_exchange_bind_t;
+
+#define AMQP_EXCHANGE_BIND_OK_METHOD ((amqp_method_number_t) 0x0028001F) /* 40, 31; 2621471 */
+typedef struct amqp_exchange_bind_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_exchange_bind_ok_t;
+
+#define AMQP_EXCHANGE_UNBIND_METHOD ((amqp_method_number_t) 0x00280028) /* 40, 40; 2621480 */
+typedef struct amqp_exchange_unbind_t_ {
+  uint16_t ticket;
+  amqp_bytes_t destination;
+  amqp_bytes_t source;
+  amqp_bytes_t routing_key;
+  amqp_boolean_t nowait;
+  amqp_table_t arguments;
+} amqp_exchange_unbind_t;
+
+#define AMQP_EXCHANGE_UNBIND_OK_METHOD ((amqp_method_number_t) 0x00280033) /* 40, 51; 2621491 */
+typedef struct amqp_exchange_unbind_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_exchange_unbind_ok_t;
+
+#define AMQP_QUEUE_DECLARE_METHOD ((amqp_method_number_t) 0x0032000A) /* 50, 10; 3276810 */
+typedef struct amqp_queue_declare_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_boolean_t passive;
+  amqp_boolean_t durable;
+  amqp_boolean_t exclusive;
+  amqp_boolean_t auto_delete;
+  amqp_boolean_t nowait;
+  amqp_table_t arguments;
+} amqp_queue_declare_t;
+
+#define AMQP_QUEUE_DECLARE_OK_METHOD ((amqp_method_number_t) 0x0032000B) /* 50, 11; 3276811 */
+typedef struct amqp_queue_declare_ok_t_ {
+  amqp_bytes_t queue;
+  uint32_t message_count;
+  uint32_t consumer_count;
+} amqp_queue_declare_ok_t;
+
+#define AMQP_QUEUE_BIND_METHOD ((amqp_method_number_t) 0x00320014) /* 50, 20; 3276820 */
+typedef struct amqp_queue_bind_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_bytes_t exchange;
+  amqp_bytes_t routing_key;
+  amqp_boolean_t nowait;
+  amqp_table_t arguments;
+} amqp_queue_bind_t;
+
+#define AMQP_QUEUE_BIND_OK_METHOD ((amqp_method_number_t) 0x00320015) /* 50, 21; 3276821 */
+typedef struct amqp_queue_bind_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_queue_bind_ok_t;
+
+#define AMQP_QUEUE_PURGE_METHOD ((amqp_method_number_t) 0x0032001E) /* 50, 30; 3276830 */
+typedef struct amqp_queue_purge_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_boolean_t nowait;
+} amqp_queue_purge_t;
+
+#define AMQP_QUEUE_PURGE_OK_METHOD ((amqp_method_number_t) 0x0032001F) /* 50, 31; 3276831 */
+typedef struct amqp_queue_purge_ok_t_ {
+  uint32_t message_count;
+} amqp_queue_purge_ok_t;
+
+#define AMQP_QUEUE_DELETE_METHOD ((amqp_method_number_t) 0x00320028) /* 50, 40; 3276840 */
+typedef struct amqp_queue_delete_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_boolean_t if_unused;
+  amqp_boolean_t if_empty;
+  amqp_boolean_t nowait;
+} amqp_queue_delete_t;
+
+#define AMQP_QUEUE_DELETE_OK_METHOD ((amqp_method_number_t) 0x00320029) /* 50, 41; 3276841 */
+typedef struct amqp_queue_delete_ok_t_ {
+  uint32_t message_count;
+} amqp_queue_delete_ok_t;
+
+#define AMQP_QUEUE_UNBIND_METHOD ((amqp_method_number_t) 0x00320032) /* 50, 50; 3276850 */
+typedef struct amqp_queue_unbind_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_bytes_t exchange;
+  amqp_bytes_t routing_key;
+  amqp_table_t arguments;
+} amqp_queue_unbind_t;
+
+#define AMQP_QUEUE_UNBIND_OK_METHOD ((amqp_method_number_t) 0x00320033) /* 50, 51; 3276851 */
+typedef struct amqp_queue_unbind_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_queue_unbind_ok_t;
+
+#define AMQP_BASIC_QOS_METHOD ((amqp_method_number_t) 0x003C000A) /* 60, 10; 3932170 */
+typedef struct amqp_basic_qos_t_ {
+  uint32_t prefetch_size;
+  uint16_t prefetch_count;
+  amqp_boolean_t global;
+} amqp_basic_qos_t;
+
+#define AMQP_BASIC_QOS_OK_METHOD ((amqp_method_number_t) 0x003C000B) /* 60, 11; 3932171 */
+typedef struct amqp_basic_qos_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_basic_qos_ok_t;
+
+#define AMQP_BASIC_CONSUME_METHOD ((amqp_method_number_t) 0x003C0014) /* 60, 20; 3932180 */
+typedef struct amqp_basic_consume_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_bytes_t consumer_tag;
+  amqp_boolean_t no_local;
+  amqp_boolean_t no_ack;
+  amqp_boolean_t exclusive;
+  amqp_boolean_t nowait;
+  amqp_table_t arguments;
+} amqp_basic_consume_t;
+
+#define AMQP_BASIC_CONSUME_OK_METHOD ((amqp_method_number_t) 0x003C0015) /* 60, 21; 3932181 */
+typedef struct amqp_basic_consume_ok_t_ {
+  amqp_bytes_t consumer_tag;
+} amqp_basic_consume_ok_t;
+
+#define AMQP_BASIC_CANCEL_METHOD ((amqp_method_number_t) 0x003C001E) /* 60, 30; 3932190 */
+typedef struct amqp_basic_cancel_t_ {
+  amqp_bytes_t consumer_tag;
+  amqp_boolean_t nowait;
+} amqp_basic_cancel_t;
+
+#define AMQP_BASIC_CANCEL_OK_METHOD ((amqp_method_number_t) 0x003C001F) /* 60, 31; 3932191 */
+typedef struct amqp_basic_cancel_ok_t_ {
+  amqp_bytes_t consumer_tag;
+} amqp_basic_cancel_ok_t;
+
+#define AMQP_BASIC_PUBLISH_METHOD ((amqp_method_number_t) 0x003C0028) /* 60, 40; 3932200 */
+typedef struct amqp_basic_publish_t_ {
+  uint16_t ticket;
+  amqp_bytes_t exchange;
+  amqp_bytes_t routing_key;
+  amqp_boolean_t mandatory;
+  amqp_boolean_t immediate;
+} amqp_basic_publish_t;
+
+#define AMQP_BASIC_RETURN_METHOD ((amqp_method_number_t) 0x003C0032) /* 60, 50; 3932210 */
+typedef struct amqp_basic_return_t_ {
+  uint16_t reply_code;
+  amqp_bytes_t reply_text;
+  amqp_bytes_t exchange;
+  amqp_bytes_t routing_key;
+} amqp_basic_return_t;
+
+#define AMQP_BASIC_DELIVER_METHOD ((amqp_method_number_t) 0x003C003C) /* 60, 60; 3932220 */
+typedef struct amqp_basic_deliver_t_ {
+  amqp_bytes_t consumer_tag;
+  uint64_t delivery_tag;
+  amqp_boolean_t redelivered;
+  amqp_bytes_t exchange;
+  amqp_bytes_t routing_key;
+} amqp_basic_deliver_t;
+
+#define AMQP_BASIC_GET_METHOD ((amqp_method_number_t) 0x003C0046) /* 60, 70; 3932230 */
+typedef struct amqp_basic_get_t_ {
+  uint16_t ticket;
+  amqp_bytes_t queue;
+  amqp_boolean_t no_ack;
+} amqp_basic_get_t;
+
+#define AMQP_BASIC_GET_OK_METHOD ((amqp_method_number_t) 0x003C0047) /* 60, 71; 3932231 */
+typedef struct amqp_basic_get_ok_t_ {
+  uint64_t delivery_tag;
+  amqp_boolean_t redelivered;
+  amqp_bytes_t exchange;
+  amqp_bytes_t routing_key;
+  uint32_t message_count;
+} amqp_basic_get_ok_t;
+
+#define AMQP_BASIC_GET_EMPTY_METHOD ((amqp_method_number_t) 0x003C0048) /* 60, 72; 3932232 */
+typedef struct amqp_basic_get_empty_t_ {
+  amqp_bytes_t cluster_id;
+} amqp_basic_get_empty_t;
+
+#define AMQP_BASIC_ACK_METHOD ((amqp_method_number_t) 0x003C0050) /* 60, 80; 3932240 */
+typedef struct amqp_basic_ack_t_ {
+  uint64_t delivery_tag;
+  amqp_boolean_t multiple;
+} amqp_basic_ack_t;
+
+#define AMQP_BASIC_REJECT_METHOD ((amqp_method_number_t) 0x003C005A) /* 60, 90; 3932250 */
+typedef struct amqp_basic_reject_t_ {
+  uint64_t delivery_tag;
+  amqp_boolean_t requeue;
+} amqp_basic_reject_t;
+
+#define AMQP_BASIC_RECOVER_ASYNC_METHOD ((amqp_method_number_t) 0x003C0064) /* 60, 100; 3932260 */
+typedef struct amqp_basic_recover_async_t_ {
+  amqp_boolean_t requeue;
+} amqp_basic_recover_async_t;
+
+#define AMQP_BASIC_RECOVER_METHOD ((amqp_method_number_t) 0x003C006E) /* 60, 110; 3932270 */
+typedef struct amqp_basic_recover_t_ {
+  amqp_boolean_t requeue;
+} amqp_basic_recover_t;
+
+#define AMQP_BASIC_RECOVER_OK_METHOD ((amqp_method_number_t) 0x003C006F) /* 60, 111; 3932271 */
+typedef struct amqp_basic_recover_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_basic_recover_ok_t;
+
+#define AMQP_BASIC_NACK_METHOD ((amqp_method_number_t) 0x003C0078) /* 60, 120; 3932280 */
+typedef struct amqp_basic_nack_t_ {
+  uint64_t delivery_tag;
+  amqp_boolean_t multiple;
+  amqp_boolean_t requeue;
+} amqp_basic_nack_t;
+
+#define AMQP_TX_SELECT_METHOD ((amqp_method_number_t) 0x005A000A) /* 90, 10; 5898250 */
+typedef struct amqp_tx_select_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_select_t;
+
+#define AMQP_TX_SELECT_OK_METHOD ((amqp_method_number_t) 0x005A000B) /* 90, 11; 5898251 */
+typedef struct amqp_tx_select_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_select_ok_t;
+
+#define AMQP_TX_COMMIT_METHOD ((amqp_method_number_t) 0x005A0014) /* 90, 20; 5898260 */
+typedef struct amqp_tx_commit_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_commit_t;
+
+#define AMQP_TX_COMMIT_OK_METHOD ((amqp_method_number_t) 0x005A0015) /* 90, 21; 5898261 */
+typedef struct amqp_tx_commit_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_commit_ok_t;
+
+#define AMQP_TX_ROLLBACK_METHOD ((amqp_method_number_t) 0x005A001E) /* 90, 30; 5898270 */
+typedef struct amqp_tx_rollback_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_rollback_t;
+
+#define AMQP_TX_ROLLBACK_OK_METHOD ((amqp_method_number_t) 0x005A001F) /* 90, 31; 5898271 */
+typedef struct amqp_tx_rollback_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_rollback_ok_t;
+
+#define AMQP_CONFIRM_SELECT_METHOD ((amqp_method_number_t) 0x0055000A) /* 85, 10; 5570570 */
+typedef struct amqp_confirm_select_t_ {
+  amqp_boolean_t nowait;
+} amqp_confirm_select_t;
+
+#define AMQP_CONFIRM_SELECT_OK_METHOD ((amqp_method_number_t) 0x0055000B) /* 85, 11; 5570571 */
+typedef struct amqp_confirm_select_ok_t_ {
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_confirm_select_ok_t;
+
+/* Class property records. */
+#define AMQP_CONNECTION_CLASS (0x000A) /* 10 */
+typedef struct amqp_connection_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_connection_properties_t;
+
+#define AMQP_CHANNEL_CLASS (0x0014) /* 20 */
+typedef struct amqp_channel_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_channel_properties_t;
+
+#define AMQP_ACCESS_CLASS (0x001E) /* 30 */
+typedef struct amqp_access_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_access_properties_t;
+
+#define AMQP_EXCHANGE_CLASS (0x0028) /* 40 */
+typedef struct amqp_exchange_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_exchange_properties_t;
+
+#define AMQP_QUEUE_CLASS (0x0032) /* 50 */
+typedef struct amqp_queue_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_queue_properties_t;
+
+#define AMQP_BASIC_CLASS (0x003C) /* 60 */
+#define AMQP_BASIC_CONTENT_TYPE_FLAG (1 << 15)
+#define AMQP_BASIC_CONTENT_ENCODING_FLAG (1 << 14)
+#define AMQP_BASIC_HEADERS_FLAG (1 << 13)
+#define AMQP_BASIC_DELIVERY_MODE_FLAG (1 << 12)
+#define AMQP_BASIC_PRIORITY_FLAG (1 << 11)
+#define AMQP_BASIC_CORRELATION_ID_FLAG (1 << 10)
+#define AMQP_BASIC_REPLY_TO_FLAG (1 << 9)
+#define AMQP_BASIC_EXPIRATION_FLAG (1 << 8)
+#define AMQP_BASIC_MESSAGE_ID_FLAG (1 << 7)
+#define AMQP_BASIC_TIMESTAMP_FLAG (1 << 6)
+#define AMQP_BASIC_TYPE_FLAG (1 << 5)
+#define AMQP_BASIC_USER_ID_FLAG (1 << 4)
+#define AMQP_BASIC_APP_ID_FLAG (1 << 3)
+#define AMQP_BASIC_CLUSTER_ID_FLAG (1 << 2)
+typedef struct amqp_basic_properties_t_ {
+  amqp_flags_t _flags;
+  amqp_bytes_t content_type;
+  amqp_bytes_t content_encoding;
+  amqp_table_t headers;
+  uint8_t delivery_mode;
+  uint8_t priority;
+  amqp_bytes_t correlation_id;
+  amqp_bytes_t reply_to;
+  amqp_bytes_t expiration;
+  amqp_bytes_t message_id;
+  uint64_t timestamp;
+  amqp_bytes_t type;
+  amqp_bytes_t user_id;
+  amqp_bytes_t app_id;
+  amqp_bytes_t cluster_id;
+} amqp_basic_properties_t;
+
+#define AMQP_TX_CLASS (0x005A) /* 90 */
+typedef struct amqp_tx_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_tx_properties_t;
+
+#define AMQP_CONFIRM_CLASS (0x0055) /* 85 */
+typedef struct amqp_confirm_properties_t_ {
+  amqp_flags_t _flags;
+  char dummy; /* Dummy field to avoid empty struct */
+} amqp_confirm_properties_t;
+
+/* API functions for methods */
+
+AMQP_PUBLIC_FUNCTION amqp_channel_open_ok_t * AMQP_CALL amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel);
+AMQP_PUBLIC_FUNCTION amqp_channel_flow_ok_t * AMQP_CALL amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t active);
+AMQP_PUBLIC_FUNCTION amqp_exchange_declare_ok_t * AMQP_CALL amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_exchange_delete_ok_t * AMQP_CALL amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, amqp_boolean_t if_unused);
+AMQP_PUBLIC_FUNCTION amqp_exchange_bind_ok_t * AMQP_CALL amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_exchange_unbind_ok_t * AMQP_CALL amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t destination, amqp_bytes_t source, amqp_bytes_t routing_key, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_queue_declare_ok_t * AMQP_CALL amqp_queue_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, amqp_boolean_t auto_delete, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_queue_bind_ok_t * AMQP_CALL amqp_queue_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_queue_purge_ok_t * AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue);
+AMQP_PUBLIC_FUNCTION amqp_queue_delete_ok_t * AMQP_CALL amqp_queue_delete(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_boolean_t if_unused, amqp_boolean_t if_empty);
+AMQP_PUBLIC_FUNCTION amqp_queue_unbind_ok_t * AMQP_CALL amqp_queue_unbind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_basic_qos_ok_t * AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, amqp_channel_t channel, uint32_t prefetch_size, uint16_t prefetch_count, amqp_boolean_t global);
+AMQP_PUBLIC_FUNCTION amqp_basic_consume_ok_t * AMQP_CALL amqp_basic_consume(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, amqp_boolean_t exclusive, amqp_table_t arguments);
+AMQP_PUBLIC_FUNCTION amqp_basic_cancel_ok_t * AMQP_CALL amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t consumer_tag);
+AMQP_PUBLIC_FUNCTION amqp_basic_recover_ok_t * AMQP_CALL amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, amqp_boolean_t requeue);
+AMQP_PUBLIC_FUNCTION amqp_tx_select_ok_t * AMQP_CALL amqp_tx_select(amqp_connection_state_t state, amqp_channel_t channel);
+AMQP_PUBLIC_FUNCTION amqp_tx_commit_ok_t * AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, amqp_channel_t channel);
+AMQP_PUBLIC_FUNCTION amqp_tx_rollback_ok_t * AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, amqp_channel_t channel);
+AMQP_PUBLIC_FUNCTION amqp_confirm_select_ok_t * AMQP_CALL amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel);
+
+AMQP_END_DECLS
+
+#endif /* AMQP_FRAMING_H */
diff --git a/modules/kazoo/deps/amqp_hostcheck.c b/modules/kazoo/deps/amqp_hostcheck.c
new file mode 100644
index 0000000..8ad2cf7
--- /dev/null
+++ b/modules/kazoo/deps/amqp_hostcheck.c
@@ -0,0 +1,201 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Copyright 1996-2014 Daniel Stenberg <daniel@haxx.se>.
+ * Copyright 2014 Michael Steinert
+ *
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization of the
+ * copyright holder.
+ */
+
+#include "amqp_private.h"
+
+#include <string.h>
+
+/* Portable, consistent toupper (remember EBCDIC). Do not use toupper()
+ * because its behavior is altered by the current locale.
+ */
+
+static char
+amqp_raw_toupper(char in)
+{
+  switch (in) {
+  case 'a':
+    return 'A';
+  case 'b':
+    return 'B';
+  case 'c':
+    return 'C';
+  case 'd':
+    return 'D';
+  case 'e':
+    return 'E';
+  case 'f':
+    return 'F';
+  case 'g':
+    return 'G';
+  case 'h':
+    return 'H';
+  case 'i':
+    return 'I';
+  case 'j':
+    return 'J';
+  case 'k':
+    return 'K';
+  case 'l':
+    return 'L';
+  case 'm':
+    return 'M';
+  case 'n':
+    return 'N';
+  case 'o':
+    return 'O';
+  case 'p':
+    return 'P';
+  case 'q':
+    return 'Q';
+  case 'r':
+    return 'R';
+  case 's':
+    return 'S';
+  case 't':
+    return 'T';
+  case 'u':
+    return 'U';
+  case 'v':
+    return 'V';
+  case 'w':
+    return 'W';
+  case 'x':
+    return 'X';
+  case 'y':
+    return 'Y';
+  case 'z':
+    return 'Z';
+  }
+  return in;
+}
+
+/*
+ * amqp_raw_equal() is for doing "raw" case insensitive strings. This is meant
+ * to be locale independent and only compare strings we know are safe for
+ * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
+ * some further explanation to why this function is necessary.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ */
+
+static int
+amqp_raw_equal(const char *first, const char *second)
+{
+  while (*first && *second) {
+    if (amqp_raw_toupper(*first) != amqp_raw_toupper(*second)) {
+      /* get out of the loop as soon as they don't match */
+      break;
+    }
+    first++;
+    second++;
+  }
+  /* we do the comparison here (possibly again), just to make sure that if
+   * the loop above is skipped because one of the strings reached zero, we
+   * must not return this as a successful match
+   */
+  return (amqp_raw_toupper(*first) == amqp_raw_toupper(*second));
+}
+
+static int
+amqp_raw_nequal(const char *first, const char *second, size_t max)
+{
+  while (*first && *second && max) {
+    if (amqp_raw_toupper(*first) != amqp_raw_toupper(*second)) {
+      break;
+    }
+    max--;
+    first++;
+    second++;
+  }
+  if (0 == max) {
+    return 1; /* they are equal this far */
+  }
+  return amqp_raw_toupper(*first) == amqp_raw_toupper(*second);
+}
+
+/*
+ * Match a hostname against a wildcard pattern.
+ * E.g.
+ *  "foo.host.com" matches "*.host.com".
+ *
+ * We use the matching rule described in RFC6125, section 6.4.3.
+ * http://tools.ietf.org/html/rfc6125#section-6.4.3
+ */
+
+static int
+amqp_hostmatch(const char *hostname, const char *pattern)
+{
+  const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
+  int wildcard_enabled;
+  size_t prefixlen, suffixlen;
+  pattern_wildcard = strchr(pattern, '*');
+  if (pattern_wildcard == NULL) {
+    return amqp_raw_equal(pattern, hostname) ? 1 : 0;
+  }
+  /* We require at least 2 dots in pattern to avoid too wide wildcard match. */
+  wildcard_enabled = 1;
+  pattern_label_end = strchr(pattern, '.');
+  if (pattern_label_end == NULL ||
+      strchr(pattern_label_end + 1, '.') == NULL ||
+      pattern_wildcard > pattern_label_end ||
+      amqp_raw_nequal(pattern, "xn--", 4)) {
+    wildcard_enabled = 0;
+  }
+  if (!wildcard_enabled) {
+    return amqp_raw_equal(pattern, hostname) ? 1 : 0;
+  }
+  hostname_label_end = strchr(hostname, '.');
+  if (hostname_label_end == NULL ||
+      !amqp_raw_equal(pattern_label_end, hostname_label_end)) {
+    return 0;
+  }
+  /* The wildcard must match at least one character, so the left-most
+   * label of the hostname is at least as large as the left-most label
+   * of the pattern.
+   */
+  if (hostname_label_end - hostname < pattern_label_end - pattern) {
+    return 0;
+  }
+  prefixlen = pattern_wildcard - pattern;
+  suffixlen = pattern_label_end - (pattern_wildcard + 1);
+  return amqp_raw_nequal(pattern, hostname, prefixlen) &&
+    amqp_raw_nequal(pattern_wildcard + 1, hostname_label_end - suffixlen,
+                    suffixlen) ? 1 : 0;
+}
+
+int
+amqp_hostcheck(const char *match_pattern, const char *hostname)
+{
+  /* sanity check */
+  if (!match_pattern || !*match_pattern || !hostname || !*hostname) {
+    return 0;
+  }
+  /* trivial case */
+  if (amqp_raw_equal(hostname, match_pattern)) {
+    return 1;
+  }
+  return amqp_hostmatch(hostname, match_pattern);
+}
diff --git a/modules/kazoo/deps/amqp_hostcheck.h b/modules/kazoo/deps/amqp_hostcheck.h
new file mode 100644
index 0000000..2832933
--- /dev/null
+++ b/modules/kazoo/deps/amqp_hostcheck.h
@@ -0,0 +1,36 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+#ifndef librabbitmq_amqp_hostcheck_h
+#define librabbitmq_amqp_hostcheck_h
+
+/*
+ * Copyright 1996-2014 Daniel Stenberg <daniel@haxx.se>.
+ * Copyright 2014 Michael Steinert
+ *
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization of the
+ * copyright holder.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+int
+amqp_hostcheck(const char *match_pattern, const char *hostname);
+
+#endif
diff --git a/modules/kazoo/deps/amqp_mem.c b/modules/kazoo/deps/amqp_mem.c
new file mode 100644
index 0000000..586117e
--- /dev/null
+++ b/modules/kazoo/deps/amqp_mem.c
@@ -0,0 +1,252 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2013
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+char const *amqp_version(void)
+{
+  return AMQP_VERSION_STRING;
+}
+
+uint32_t amqp_version_number(void)
+{
+  return AMQP_VERSION;
+}
+
+void init_amqp_pool(amqp_pool_t *pool, size_t pagesize)
+{
+  pool->pagesize = pagesize ? pagesize : 4096;
+
+  pool->pages.num_blocks = 0;
+  pool->pages.blocklist = NULL;
+
+  pool->large_blocks.num_blocks = 0;
+  pool->large_blocks.blocklist = NULL;
+
+  pool->next_page = 0;
+  pool->alloc_block = NULL;
+  pool->alloc_used = 0;
+}
+
+static void empty_blocklist(amqp_pool_blocklist_t *x)
+{
+  int i;
+
+  for (i = 0; i < x->num_blocks; i++) {
+    free(x->blocklist[i]);
+  }
+  if (x->blocklist != NULL) {
+    free(x->blocklist);
+  }
+  x->num_blocks = 0;
+  x->blocklist = NULL;
+}
+
+void recycle_amqp_pool(amqp_pool_t *pool)
+{
+  empty_blocklist(&pool->large_blocks);
+  pool->next_page = 0;
+  pool->alloc_block = NULL;
+  pool->alloc_used = 0;
+}
+
+void empty_amqp_pool(amqp_pool_t *pool)
+{
+  recycle_amqp_pool(pool);
+  empty_blocklist(&pool->pages);
+}
+
+/* Returns 1 on success, 0 on failure */
+static int record_pool_block(amqp_pool_blocklist_t *x, void *block)
+{
+  size_t blocklistlength = sizeof(void *) * (x->num_blocks + 1);
+
+  if (x->blocklist == NULL) {
+    x->blocklist = malloc(blocklistlength);
+    if (x->blocklist == NULL) {
+      return 0;
+    }
+  } else {
+    void *newbl = realloc(x->blocklist, blocklistlength);
+    if (newbl == NULL) {
+      return 0;
+    }
+    x->blocklist = newbl;
+  }
+
+  x->blocklist[x->num_blocks] = block;
+  x->num_blocks++;
+  return 1;
+}
+
+void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount)
+{
+  if (amount == 0) {
+    return NULL;
+  }
+
+  amount = (amount + 7) & (~7); /* round up to nearest 8-byte boundary */
+
+  if (amount > pool->pagesize) {
+    void *result = calloc(1, amount);
+    if (result == NULL) {
+      return NULL;
+    }
+    if (!record_pool_block(&pool->large_blocks, result)) {
+      return NULL;
+    }
+    return result;
+  }
+
+  if (pool->alloc_block != NULL) {
+    assert(pool->alloc_used <= pool->pagesize);
+
+    if (pool->alloc_used + amount <= pool->pagesize) {
+      void *result = pool->alloc_block + pool->alloc_used;
+      pool->alloc_used += amount;
+      return result;
+    }
+  }
+
+  if (pool->next_page >= pool->pages.num_blocks) {
+    pool->alloc_block = calloc(1, pool->pagesize);
+    if (pool->alloc_block == NULL) {
+      return NULL;
+    }
+    if (!record_pool_block(&pool->pages, pool->alloc_block)) {
+      return NULL;
+    }
+    pool->next_page = pool->pages.num_blocks;
+  } else {
+    pool->alloc_block = pool->pages.blocklist[pool->next_page];
+    pool->next_page++;
+  }
+
+  pool->alloc_used = amount;
+
+  return pool->alloc_block;
+}
+
+void amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, amqp_bytes_t *output)
+{
+  output->len = amount;
+  output->bytes = amqp_pool_alloc(pool, amount);
+}
+
+amqp_bytes_t amqp_cstring_bytes(char const *cstr)
+{
+  amqp_bytes_t result;
+  result.len = strlen(cstr);
+  result.bytes = (void *) cstr;
+  return result;
+}
+
+amqp_bytes_t amqp_bytes_malloc_dup(amqp_bytes_t src)
+{
+  amqp_bytes_t result;
+  result.len = src.len;
+  result.bytes = malloc(src.len);
+  if (result.bytes != NULL) {
+    memcpy(result.bytes, src.bytes, src.len);
+  }
+  return result;
+}
+
+amqp_bytes_t amqp_bytes_malloc(size_t amount)
+{
+  amqp_bytes_t result;
+  result.len = amount;
+  result.bytes = malloc(amount); /* will return NULL if it fails */
+  return result;
+}
+
+void amqp_bytes_free(amqp_bytes_t bytes)
+{
+  free(bytes.bytes);
+}
+
+amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_pool_table_entry_t *entry;
+  size_t index = channel % POOL_TABLE_SIZE;
+
+  entry = state->pool_table[index];
+
+  for ( ; NULL != entry; entry = entry->next) {
+    if (channel == entry->channel) {
+      return &entry->pool;
+    }
+  }
+
+  entry = malloc(sizeof(amqp_pool_table_entry_t));
+  if (NULL == entry) {
+    return NULL;
+  }
+
+  entry->channel = channel;
+  entry->next = state->pool_table[index];
+  state->pool_table[index] = entry;
+
+  init_amqp_pool(&entry->pool, state->frame_max);
+
+  return &entry->pool;
+}
+
+amqp_pool_t *amqp_get_channel_pool(amqp_connection_state_t state, amqp_channel_t channel)
+{
+  amqp_pool_table_entry_t *entry;
+  size_t index = channel % POOL_TABLE_SIZE;
+
+  entry = state->pool_table[index];
+
+  for ( ; NULL != entry; entry = entry->next) {
+    if (channel == entry->channel) {
+      return &entry->pool;
+    }
+  }
+
+  return NULL;
+}
diff --git a/modules/kazoo/deps/amqp_openssl.c b/modules/kazoo/deps/amqp_openssl.c
new file mode 100644
index 0000000..393a84e
--- /dev/null
+++ b/modules/kazoo/deps/amqp_openssl.c
@@ -0,0 +1,626 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2014 Alan Antonuk.
+ * All Rights Reserved.
+ *
+ * Portions created by Michael Steinert are Copyright (c) 2012-2014 Michael
+ * Steinert. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_ssl_socket.h"
+#include "amqp_socket.h"
+#include "amqp_hostcheck.h"
+#include "amqp_private.h"
+#include "threads.h"
+
+#include <ctype.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static int initialize_openssl(void);
+static int destroy_openssl(void);
+
+static int open_ssl_connections = 0;
+static amqp_boolean_t do_initialize_openssl = 1;
+static amqp_boolean_t openssl_initialized = 0;
+
+#ifdef ENABLE_THREAD_SAFETY
+static unsigned long amqp_ssl_threadid_callback(void);
+static void amqp_ssl_locking_callback(int mode, int n, const char *file, int line);
+
+#ifdef _WIN32
+static long win32_create_mutex = 0;
+static pthread_mutex_t openssl_init_mutex = NULL;
+#else
+static pthread_mutex_t openssl_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+static pthread_mutex_t *amqp_openssl_lockarray = NULL;
+#endif /* ENABLE_THREAD_SAFETY */
+
+struct amqp_ssl_socket_t {
+  const struct amqp_socket_class_t *klass;
+  SSL_CTX *ctx;
+  int sockfd;
+  SSL *ssl;
+  char *buffer;
+  size_t length;
+  amqp_boolean_t verify;
+  int internal_error;
+};
+
+static ssize_t
+amqp_ssl_socket_send(void *base,
+                     const void *buf,
+                     size_t len)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+  ssize_t res;
+  ERR_clear_error();
+  self->internal_error = 0;
+
+  /* This will only return on error, or once the whole buffer has been
+   * written to the SSL stream. See SSL_MODE_ENABLE_PARTIAL_WRITE */
+  res = SSL_write(self->ssl, buf, len);
+  if (0 >= res) {
+    self->internal_error = SSL_get_error(self->ssl, res);
+    /* TODO: Close connection if it isn't already? */
+    /* TODO: Possibly be more intelligent in reporting WHAT went wrong */
+    switch (self->internal_error) {
+      case SSL_ERROR_ZERO_RETURN:
+        res = AMQP_STATUS_CONNECTION_CLOSED;
+        break;
+      default:
+        res = AMQP_STATUS_SSL_ERROR;
+        break;
+    }
+  } else {
+    self->internal_error = 0;
+    res = AMQP_STATUS_OK;
+  }
+
+  return res;
+}
+
+static ssize_t
+amqp_ssl_socket_writev(void *base,
+                       struct iovec *iov,
+                       int iovcnt)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+  ssize_t ret = -1;
+  char *bufferp;
+  size_t bytes;
+  int i;
+  bytes = 0;
+  for (i = 0; i < iovcnt; ++i) {
+    bytes += iov[i].iov_len;
+  }
+  if (self->length < bytes) {
+    self->buffer = realloc(self->buffer, bytes);
+    if (!self->buffer) {
+      self->length = 0;
+      ret = AMQP_STATUS_NO_MEMORY;
+      goto exit;
+    }
+    self->length = bytes;
+  }
+  bufferp = self->buffer;
+  for (i = 0; i < iovcnt; ++i) {
+    memcpy(bufferp, iov[i].iov_base, iov[i].iov_len);
+    bufferp += iov[i].iov_len;
+  }
+  ret = amqp_ssl_socket_send(self, self->buffer, bytes);
+exit:
+  return ret;
+}
+
+static ssize_t
+amqp_ssl_socket_recv(void *base,
+                     void *buf,
+                     size_t len,
+                     AMQP_UNUSED int flags)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+  ssize_t received;
+  ERR_clear_error();
+  self->internal_error = 0;
+
+  received = SSL_read(self->ssl, buf, len);
+  if (0 >= received) {
+    self->internal_error = SSL_get_error(self->ssl, received);
+    switch(self->internal_error) {
+    case SSL_ERROR_ZERO_RETURN:
+      received = AMQP_STATUS_CONNECTION_CLOSED;
+      break;
+    default:
+      received = AMQP_STATUS_SSL_ERROR;
+      break;
+    }
+  }
+
+  return received;
+}
+
+static int
+amqp_ssl_socket_verify_hostname(void *base, const char *host)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+  unsigned char *utf8_value = NULL, *cp, ch;
+  int pos, utf8_length, status = 0;
+  ASN1_STRING *entry_string;
+  X509_NAME_ENTRY *entry;
+  X509_NAME *name;
+  X509 *peer;
+  peer = SSL_get_peer_certificate(self->ssl);
+  if (!peer) {
+    goto error;
+  }
+  name = X509_get_subject_name(peer);
+  if (!name) {
+    goto error;
+  }
+  pos = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
+  if (0 > pos) {
+    goto error;
+  }
+  entry = X509_NAME_get_entry(name, pos);
+  if (!entry) {
+    goto error;
+  }
+  entry_string = X509_NAME_ENTRY_get_data(entry);
+  if (!entry_string) {
+    goto error;
+  }
+  utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_string);
+  if (0 > utf8_length) {
+    goto error;
+  }
+  while (utf8_length > 0 && utf8_value[utf8_length - 1] == 0) {
+    --utf8_length;
+  }
+  if (utf8_length >= 256) {
+    goto error;
+  }
+  if ((size_t)utf8_length != strlen((char *)utf8_value)) {
+    goto error;
+  }
+  for (cp = utf8_value; (ch = *cp) != '\0'; ++cp) {
+    if (isascii(ch) && !isprint(ch)) {
+      goto error;
+    }
+  }
+  if (!amqp_hostcheck((char *)utf8_value, host)) {
+    goto error;
+  }
+exit:
+  OPENSSL_free(utf8_value);
+  return status;
+error:
+  status = -1;
+  goto exit;
+}
+
+static int
+amqp_ssl_socket_open(void *base, const char *host, int port, struct timeval *timeout)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+  long result;
+  int status;
+  ERR_clear_error();
+
+  self->ssl = SSL_new(self->ctx);
+  if (!self->ssl) {
+    self->internal_error = ERR_peek_error();
+    status = AMQP_STATUS_SSL_ERROR;
+    goto exit;
+  }
+
+  SSL_set_mode(self->ssl, SSL_MODE_AUTO_RETRY);
+  self->sockfd = amqp_open_socket_noblock(host, port, timeout);
+  if (0 > self->sockfd) {
+    status = self->sockfd;
+    self->internal_error = amqp_os_socket_error();
+    self->sockfd = -1;
+    goto error_out1;
+  }
+
+  status = SSL_set_fd(self->ssl, self->sockfd);
+  if (!status) {
+    self->internal_error = SSL_get_error(self->ssl, status);
+    status = AMQP_STATUS_SSL_ERROR;
+    goto error_out2;
+  }
+
+  status = SSL_connect(self->ssl);
+  if (!status) {
+    self->internal_error = SSL_get_error(self->ssl, status);
+    status = AMQP_STATUS_SSL_CONNECTION_FAILED;
+    goto error_out2;
+  }
+
+  result = SSL_get_verify_result(self->ssl);
+  if (X509_V_OK != result) {
+    self->internal_error = result;
+    status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED;
+    goto error_out3;
+  }
+  if (self->verify) {
+    int verify_status = amqp_ssl_socket_verify_hostname(self, host);
+    if (verify_status) {
+      self->internal_error = 0;
+      status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED;
+      goto error_out3;
+    }
+  }
+
+  self->internal_error = 0;
+  status = AMQP_STATUS_OK;
+
+exit:
+  return status;
+
+error_out3:
+  SSL_shutdown(self->ssl);
+error_out2:
+  amqp_os_socket_close(self->sockfd);
+  self->sockfd = -1;
+error_out1:
+  SSL_free(self->ssl);
+  self->ssl = NULL;
+  goto exit;
+}
+
+static int
+amqp_ssl_socket_close(void *base)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+
+  if (self->ssl) {
+    SSL_shutdown(self->ssl);
+    SSL_free(self->ssl);
+    self->ssl = NULL;
+  }
+
+  if (-1 != self->sockfd) {
+    if (amqp_os_socket_close(self->sockfd)) {
+      return AMQP_STATUS_SOCKET_ERROR;
+    }
+
+    self->sockfd = -1;
+  }
+
+  return AMQP_STATUS_OK;
+}
+
+static int
+amqp_ssl_socket_get_sockfd(void *base)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+  return self->sockfd;
+}
+
+static void
+amqp_ssl_socket_delete(void *base)
+{
+  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
+
+  if (self) {
+    amqp_ssl_socket_close(self);
+
+    SSL_CTX_free(self->ctx);
+    free(self->buffer);
+    free(self);
+  }
+  destroy_openssl();
+}
+
+static const struct amqp_socket_class_t amqp_ssl_socket_class = {
+  amqp_ssl_socket_writev, /* writev */
+  amqp_ssl_socket_send, /* send */
+  amqp_ssl_socket_recv, /* recv */
+  amqp_ssl_socket_open, /* open */
+  amqp_ssl_socket_close, /* close */
+  amqp_ssl_socket_get_sockfd, /* get_sockfd */
+  amqp_ssl_socket_delete /* delete */
+};
+
+amqp_socket_t *
+amqp_ssl_socket_new(amqp_connection_state_t state)
+{
+  struct amqp_ssl_socket_t *self = calloc(1, sizeof(*self));
+  int status;
+  if (!self) {
+    return NULL;
+  }
+
+  self->sockfd = -1;
+  self->klass = &amqp_ssl_socket_class;
+  self->verify = 1;
+
+  status = initialize_openssl();
+  if (status) {
+    goto error;
+  }
+
+  self->ctx = SSL_CTX_new(SSLv23_client_method());
+  if (!self->ctx) {
+    goto error;
+  }
+
+  amqp_set_socket(state, (amqp_socket_t *)self);
+
+  return (amqp_socket_t *)self;
+error:
+  amqp_ssl_socket_delete((amqp_socket_t *)self);
+  return NULL;
+}
+
+int
+amqp_ssl_socket_set_cacert(amqp_socket_t *base,
+                           const char *cacert)
+{
+  int status;
+  struct amqp_ssl_socket_t *self;
+  if (base->klass != &amqp_ssl_socket_class) {
+    amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
+  }
+  self = (struct amqp_ssl_socket_t *)base;
+  status = SSL_CTX_load_verify_locations(self->ctx, cacert, NULL);
+  if (1 != status) {
+    return AMQP_STATUS_SSL_ERROR;
+  }
+  return AMQP_STATUS_OK;
+}
+
+int
+amqp_ssl_socket_set_key(amqp_socket_t *base,
+                        const char *cert,
+                        const char *key)
+{
+  int status;
+  struct amqp_ssl_socket_t *self;
+  if (base->klass != &amqp_ssl_socket_class) {
+    amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
+  }
+  self = (struct amqp_ssl_socket_t *)base;
+  status = SSL_CTX_use_certificate_chain_file(self->ctx, cert);
+  if (1 != status) {
+    return AMQP_STATUS_SSL_ERROR;
+  }
+  status = SSL_CTX_use_PrivateKey_file(self->ctx, key,
+                                       SSL_FILETYPE_PEM);
+  if (1 != status) {
+    return AMQP_STATUS_SSL_ERROR;
+  }
+  return AMQP_STATUS_OK;
+}
+
+static int
+password_cb(AMQP_UNUSED char *buffer,
+            AMQP_UNUSED int length,
+            AMQP_UNUSED int rwflag,
+            AMQP_UNUSED void *user_data)
+{
+  amqp_abort("rabbitmq-c does not support password protected keys");
+  return 0;
+}
+
+int
+amqp_ssl_socket_set_key_buffer(amqp_socket_t *base,
+                               const char *cert,
+                               const void *key,
+                               size_t n)
+{
+  int status = AMQP_STATUS_OK;
+  BIO *buf = NULL;
+  RSA *rsa = NULL;
+  struct amqp_ssl_socket_t *self;
+  if (base->klass != &amqp_ssl_socket_class) {
+    amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
+  }
+  self = (struct amqp_ssl_socket_t *)base;
+  status = SSL_CTX_use_certificate_chain_file(self->ctx, cert);
+  if (1 != status) {
+    return AMQP_STATUS_SSL_ERROR;
+  }
+  buf = BIO_new_mem_buf((void *)key, n);
+  if (!buf) {
+    goto error;
+  }
+  rsa = PEM_read_bio_RSAPrivateKey(buf, NULL, password_cb, NULL);
+  if (!rsa) {
+    goto error;
+  }
+  status = SSL_CTX_use_RSAPrivateKey(self->ctx, rsa);
+  if (1 != status) {
+    goto error;
+  }
+exit:
+  BIO_vfree(buf);
+  RSA_free(rsa);
+  return status;
+error:
+  status = AMQP_STATUS_SSL_ERROR;
+  goto exit;
+}
+
+int
+amqp_ssl_socket_set_cert(amqp_socket_t *base,
+                         const char *cert)
+{
+  int status;
+  struct amqp_ssl_socket_t *self;
+  if (base->klass != &amqp_ssl_socket_class) {
+    amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
+  }
+  self = (struct amqp_ssl_socket_t *)base;
+  status = SSL_CTX_use_certificate_chain_file(self->ctx, cert);
+  if (1 != status) {
+    return AMQP_STATUS_SSL_ERROR;
+  }
+  return AMQP_STATUS_OK;
+}
+
+void
+amqp_ssl_socket_set_verify(amqp_socket_t *base,
+                           amqp_boolean_t verify)
+{
+  struct amqp_ssl_socket_t *self;
+  if (base->klass != &amqp_ssl_socket_class) {
+    amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
+  }
+  self = (struct amqp_ssl_socket_t *)base;
+  self->verify = verify;
+}
+
+void
+amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize)
+{
+  if (!openssl_initialized) {
+    do_initialize_openssl = do_initialize;
+  }
+}
+
+#ifdef ENABLE_THREAD_SAFETY
+unsigned long
+amqp_ssl_threadid_callback(void)
+{
+  return (unsigned long)pthread_self();
+}
+
+void
+amqp_ssl_locking_callback(int mode, int n,
+                          AMQP_UNUSED const char *file,
+                          AMQP_UNUSED int line)
+{
+  if (mode & CRYPTO_LOCK) {
+    if (pthread_mutex_lock(&amqp_openssl_lockarray[n])) {
+      amqp_abort("Runtime error: Failure in trying to lock OpenSSL mutex");
+    }
+  } else {
+    if (pthread_mutex_unlock(&amqp_openssl_lockarray[n])) {
+      amqp_abort("Runtime error: Failure in trying to unlock OpenSSL mutex");
+    }
+  }
+}
+#endif /* ENABLE_THREAD_SAFETY */
+
+static int
+initialize_openssl(void)
+{
+#ifdef ENABLE_THREAD_SAFETY
+#ifdef _WIN32
+  /* No such thing as PTHREAD_INITIALIZE_MUTEX macro on Win32, so we use this */
+  if (NULL == openssl_init_mutex) {
+    while (InterlockedExchange(&win32_create_mutex, 1) == 1)
+      /* Loop, someone else is holding this lock */ ;
+
+    if (NULL == openssl_init_mutex) {
+      if (pthread_mutex_init(&openssl_init_mutex, NULL)) {
+        return -1;
+      }
+    }
+    InterlockedExchange(&win32_create_mutex, 0);
+  }
+#endif /* _WIN32 */
+
+  if (pthread_mutex_lock(&openssl_init_mutex)) {
+    return -1;
+  }
+#endif /* ENABLE_THREAD_SAFETY */
+  if (do_initialize_openssl) {
+#ifdef ENABLE_THREAD_SAFETY
+    if (NULL == amqp_openssl_lockarray) {
+      int i = 0;
+      amqp_openssl_lockarray = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t));
+      if (!amqp_openssl_lockarray) {
+        pthread_mutex_unlock(&openssl_init_mutex);
+        return -1;
+      }
+      for (i = 0; i < CRYPTO_num_locks(); ++i) {
+        if (pthread_mutex_init(&amqp_openssl_lockarray[i], NULL)) {
+          free(amqp_openssl_lockarray);
+          amqp_openssl_lockarray = NULL;
+          pthread_mutex_unlock(&openssl_init_mutex);
+          return -1;
+        }
+      }
+    }
+
+    if (0 == open_ssl_connections) {
+      CRYPTO_set_id_callback(amqp_ssl_threadid_callback);
+      CRYPTO_set_locking_callback(amqp_ssl_locking_callback);
+    }
+#endif /* ENABLE_THREAD_SAFETY */
+
+    if (!openssl_initialized) {
+      OPENSSL_config(NULL);
+
+      SSL_library_init();
+      SSL_load_error_strings();
+
+      openssl_initialized = 1;
+    }
+  }
+
+  ++open_ssl_connections;
+
+#ifdef ENABLE_THREAD_SAFETY
+  pthread_mutex_unlock(&openssl_init_mutex);
+#endif /* ENABLE_THREAD_SAFETY */
+  return 0;
+}
+
+static int
+destroy_openssl(void)
+{
+#ifdef ENABLE_THREAD_SAFETY
+  if (pthread_mutex_lock(&openssl_init_mutex)) {
+    return -1;
+  }
+#endif /* ENABLE_THREAD_SAFETY */
+
+  if (open_ssl_connections > 0) {
+    --open_ssl_connections;
+  }
+
+#ifdef ENABLE_THREAD_SAFETY
+  if (0 == open_ssl_connections && do_initialize_openssl) {
+    /* Unsetting these allows the rabbitmq-c library to be unloaded
+     * safely. We do leak the amqp_openssl_lockarray. Which is only
+     * an issue if you repeatedly unload and load the library
+     */
+    CRYPTO_set_locking_callback(NULL);
+    CRYPTO_set_id_callback(NULL);
+  }
+
+  pthread_mutex_unlock(&openssl_init_mutex);
+#endif /* ENABLE_THREAD_SAFETY */
+  return 0;
+}
diff --git a/modules/kazoo/deps/amqp_private.h b/modules/kazoo/deps/amqp_private.h
new file mode 100644
index 0000000..77a8f39
--- /dev/null
+++ b/modules/kazoo/deps/amqp_private.h
@@ -0,0 +1,363 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+#ifndef librabbitmq_amqp_private_h
+#define librabbitmq_amqp_private_h
+
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2014
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define AMQ_COPYRIGHT "Copyright (c) 2007-2014 VMWare Inc, Tony Garnock-Jones," \
+                      " and Alan Antonuk."
+
+#include "amqp.h"
+#include "amqp_framing.h"
+#include <string.h>
+
+#ifdef _WIN32
+# ifndef WINVER
+/* WINVER 0x0502 is WinXP SP2+, Windows Server 2003 SP1+
+ * See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx#macros_for_conditional_declarations */
+#  define WINVER 0x0502
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+# endif
+# include <Winsock2.h>
+#else
+# include <arpa/inet.h>
+# include <sys/uio.h>
+#endif
+
+/* GCC attributes */
+#if __GNUC__ > 2 | (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define AMQP_NORETURN \
+  __attribute__ ((__noreturn__))
+#define AMQP_UNUSED \
+  __attribute__ ((__unused__))
+#else
+#define AMQP_NORETURN
+#define AMQP_UNUSED
+#endif
+
+#if __GNUC__ >= 4
+#define AMQP_PRIVATE \
+  __attribute__ ((visibility ("hidden")))
+#else
+#define AMQP_PRIVATE
+#endif
+
+char *
+amqp_os_error_string(int err);
+
+#ifdef WITH_SSL
+char *
+amqp_ssl_error_string(int err);
+#endif
+
+#include "amqp_socket.h"
+#include "amqp_timer.h"
+
+/*
+ * Connection states: XXX FIX THIS
+ *
+ * - CONNECTION_STATE_INITIAL: The initial state, when we cannot be
+ *   sure if the next thing we will get is the first AMQP frame, or a
+ *   protocol header from the server.
+ *
+ * - CONNECTION_STATE_IDLE: The normal state between
+ *   frames. Connections may only be reconfigured, and the
+ *   connection's pools recycled, when in this state. Whenever we're
+ *   in this state, the inbound_buffer's bytes pointer must be NULL;
+ *   any other state, and it must point to a block of memory allocated
+ *   from the frame_pool.
+ *
+ * - CONNECTION_STATE_HEADER: Some bytes of an incoming frame have
+ *   been seen, but not a complete frame header's worth.
+ *
+ * - CONNECTION_STATE_BODY: A complete frame header has been seen, but
+ *   the frame is not yet complete. When it is completed, it will be
+ *   returned, and the connection will return to IDLE state.
+ *
+ */
+typedef enum amqp_connection_state_enum_ {
+  CONNECTION_STATE_IDLE = 0,
+  CONNECTION_STATE_INITIAL,
+  CONNECTION_STATE_HEADER,
+  CONNECTION_STATE_BODY
+} amqp_connection_state_enum;
+
+/* 7 bytes up front, then payload, then 1 byte footer */
+#define HEADER_SIZE 7
+#define FOOTER_SIZE 1
+
+#define AMQP_PSEUDOFRAME_PROTOCOL_HEADER 'A'
+
+typedef struct amqp_link_t_ {
+  struct amqp_link_t_ *next;
+  void *data;
+} amqp_link_t;
+
+#define POOL_TABLE_SIZE 16
+
+typedef struct amqp_pool_table_entry_t_ {
+  struct amqp_pool_table_entry_t_ *next;
+  amqp_pool_t pool;
+  amqp_channel_t channel;
+} amqp_pool_table_entry_t;
+
+struct amqp_connection_state_t_ {
+  amqp_pool_table_entry_t *pool_table[POOL_TABLE_SIZE];
+
+  amqp_connection_state_enum state;
+
+  int channel_max;
+  int frame_max;
+  int heartbeat;
+
+  /* buffer for holding frame headers.  Allows us to delay allocating
+   * the raw frame buffer until the type, channel, and size are all known
+   */
+  char header_buffer[HEADER_SIZE + 1];
+  amqp_bytes_t inbound_buffer;
+
+  size_t inbound_offset;
+  size_t target_size;
+
+  amqp_bytes_t outbound_buffer;
+
+  amqp_socket_t *socket;
+
+  amqp_bytes_t sock_inbound_buffer;
+  size_t sock_inbound_offset;
+  size_t sock_inbound_limit;
+
+  amqp_link_t *first_queued_frame;
+  amqp_link_t *last_queued_frame;
+
+  amqp_rpc_reply_t most_recent_api_result;
+
+  uint64_t next_recv_heartbeat;
+  uint64_t next_send_heartbeat;
+
+  amqp_table_t server_properties;
+  amqp_pool_t properties_pool;
+};
+
+amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t connection, amqp_channel_t channel);
+amqp_pool_t *amqp_get_channel_pool(amqp_connection_state_t state, amqp_channel_t channel);
+
+static inline amqp_boolean_t amqp_heartbeat_enabled(amqp_connection_state_t state)
+{
+  return (state->heartbeat > 0);
+}
+
+static inline uint64_t amqp_calc_next_send_heartbeat(amqp_connection_state_t state, uint64_t cur)
+{
+  return cur + ((uint64_t)state->heartbeat * AMQP_NS_PER_S);
+}
+
+static inline uint64_t amqp_calc_next_recv_heartbeat(amqp_connection_state_t state, uint64_t cur)
+{
+  return cur + ((uint64_t)state->heartbeat * 2 * AMQP_NS_PER_S);
+}
+
+int amqp_try_recv(amqp_connection_state_t state, uint64_t current_time);
+
+static inline void *amqp_offset(void *data, size_t offset)
+{
+  return (char *)data + offset;
+}
+
+/* This macro defines the encoding and decoding functions associated with a
+   simple type. */
+
+#define DECLARE_CODEC_BASE_TYPE(bits, htonx, ntohx)                           \
+                                                                              \
+  static inline void amqp_e##bits(void *data, size_t offset,                  \
+                                  uint##bits##_t val)                         \
+  {                                                                           \
+    /* The AMQP data might be unaligned. So we encode and then copy the       \
+             result into place. */                                            \
+    uint##bits##_t res = htonx(val);                                          \
+    memcpy(amqp_offset(data, offset), &res, bits/8);                          \
+  }                                                                           \
+                                                                              \
+  static inline uint##bits##_t amqp_d##bits(void *data, size_t offset)        \
+  {                                                                           \
+    /* The AMQP data might be unaligned.  So we copy the source value         \
+             into a variable and then decode it. */                           \
+    uint##bits##_t val;                                                       \
+    memcpy(&val, amqp_offset(data, offset), bits/8);                          \
+    return ntohx(val);                                                        \
+  }                                                                           \
+                                                                              \
+  static inline int amqp_encode_##bits(amqp_bytes_t encoded, size_t *offset,  \
+                                       uint##bits##_t input)                  \
+                                                                              \
+  {                                                                           \
+    size_t o = *offset;                                                       \
+    if ((*offset = o + bits / 8) <= encoded.len) {                            \
+      amqp_e##bits(encoded.bytes, o, input);                                  \
+      return 1;                                                               \
+    }                                                                         \
+    else {                                                                    \
+      return 0;                                                               \
+    }                                                                         \
+  }                                                                           \
+                                                                              \
+  static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset,  \
+                                       uint##bits##_t *output)                \
+                                                                              \
+  {                                                                           \
+    size_t o = *offset;                                                       \
+    if ((*offset = o + bits / 8) <= encoded.len) {                            \
+      *output = amqp_d##bits(encoded.bytes, o);                               \
+      return 1;                                                               \
+    }                                                                         \
+    else {                                                                    \
+      return 0;                                                               \
+    }                                                                         \
+  }
+
+/* Determine byte order */
+#if defined(__GLIBC__)
+# include <endian.h>
+# if (__BYTE_ORDER == __LITTLE_ENDIAN)
+#  define AMQP_LITTLE_ENDIAN
+# elif (__BYTE_ORDER == __BIG_ENDIAN)
+#  define AMQP_BIG_ENDIAN
+# else
+/* Don't define anything */
+# endif
+#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) ||                   \
+      defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
+# define AMQP_BIG_ENDIAN
+#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) ||                   \
+      defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+# define AMQP_LITTLE_ENDIAN
+#elif defined(__hppa__) || defined(__HPPA__) || defined(__hppa) ||          \
+      defined(_POWER) || defined(__powerpc__) || defined(__ppc___) ||       \
+      defined(_MIPSEB) || defined(__s390__) ||                              \
+      defined(__sparc) || defined(__sparc__)
+# define AMQP_BIG_ENDIAN
+#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) ||        \
+      defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) ||       \
+      defined(__ia64) || defined(__ia64__) || defined(_M_IA64) ||           \
+      defined(__arm__) || defined(_M_ARM) ||                                \
+      defined(__i386__) || defined(_M_IX86)
+# define AMQP_LITTLE_ENDIAN
+#else
+/* Don't define anything */
+#endif
+
+#if defined(AMQP_LITTLE_ENDIAN)
+
+#define DECLARE_XTOXLL(func)                        \
+  static inline uint64_t func##ll(uint64_t val)     \
+  {                                                 \
+    union {                                         \
+      uint64_t whole;                               \
+      uint32_t halves[2];                           \
+    } u;                                            \
+    uint32_t t;                                     \
+    u.whole = val;                                  \
+    t = u.halves[0];                                \
+    u.halves[0] = func##l(u.halves[1]);             \
+    u.halves[1] = func##l(t);                       \
+    return u.whole;                                 \
+  }
+
+#elif defined(AMQP_BIG_ENDIAN)
+
+#define DECLARE_XTOXLL(func)                        \
+  static inline uint64_t func##ll(uint64_t val)     \
+  {                                                 \
+    union {                                         \
+      uint64_t whole;                               \
+      uint32_t halves[2];                           \
+    } u;                                            \
+    u.whole = val;                                  \
+    u.halves[0] = func##l(u.halves[0]);             \
+    u.halves[1] = func##l(u.halves[1]);             \
+    return u.whole;                                 \
+  }
+
+#else
+# error Endianness not known
+#endif
+
+#ifndef HAVE_HTONLL
+DECLARE_XTOXLL(hton)
+DECLARE_XTOXLL(ntoh)
+#endif
+
+DECLARE_CODEC_BASE_TYPE(8, (uint8_t), (uint8_t))
+DECLARE_CODEC_BASE_TYPE(16, htons, ntohs)
+DECLARE_CODEC_BASE_TYPE(32, htonl, ntohl)
+DECLARE_CODEC_BASE_TYPE(64, htonll, ntohll)
+
+static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset,
+                                    amqp_bytes_t input)
+{
+  size_t o = *offset;
+  if ((*offset = o + input.len) <= encoded.len) {
+    memcpy(amqp_offset(encoded.bytes, o), input.bytes, input.len);
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+static inline int amqp_decode_bytes(amqp_bytes_t encoded, size_t *offset,
+                                    amqp_bytes_t *output, size_t len)
+{
+  size_t o = *offset;
+  if ((*offset = o + len) <= encoded.len) {
+    output->bytes = amqp_offset(encoded.bytes, o);
+    output->len = len;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+AMQP_NORETURN
+void
+amqp_abort(const char *fmt, ...);
+
+#endif
diff --git a/modules/kazoo/deps/amqp_socket.c b/modules/kazoo/deps/amqp_socket.c
new file mode 100644
index 0000000..29a7389
--- /dev/null
+++ b/modules/kazoo/deps/amqp_socket.c
@@ -0,0 +1,1388 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2014
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include "amqp_timer.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <errno.h>
+
+#ifdef _WIN32
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+# endif
+# include <Winsock2.h>
+# include <ws2tcpip.h>
+#else
+# include <sys/types.h>      /* On older BSD this must come before net includes */
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <sys/uio.h>
+# include <fcntl.h>
+# include <poll.h>
+# include <unistd.h>
+#endif
+
+#ifdef _WIN32
+# define poll(fdarray, nfds, timeout) WSAPoll(fdarray, nfds, timeout)
+#endif
+
+static int
+amqp_os_socket_init(void)
+{
+#ifdef _WIN32
+  static called_wsastartup = 0;
+  if (!called_wsastartup) {
+    WSADATA data;
+    int res = WSAStartup(0x0202, &data);
+    if (res) {
+      return AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR;
+    }
+
+    called_wsastartup = 1;
+  }
+  return AMQP_STATUS_OK;
+
+#else
+  return AMQP_STATUS_OK;
+#endif
+}
+
+static int
+amqp_os_socket_socket(int domain, int type, int protocol)
+{
+#ifdef _WIN32
+    /*
+      This cast is to squash warnings on Win64, see:
+      http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64
+    */
+  return (int)socket(domain, type, protocol);
+#else
+  int flags;
+
+  int s = socket(domain, type, protocol);
+  if (s < 0) {
+    return s;
+  }
+
+  /* Always enable CLOEXEC on the socket */
+  flags = fcntl(s, F_GETFD);
+  if (flags == -1
+      || fcntl(s, F_SETFD, (long)(flags | FD_CLOEXEC)) == -1) {
+    int e = errno;
+    close(s);
+    errno = e;
+    return -1;
+  }
+
+  return s;
+
+#endif
+}
+
+static int
+amqp_os_socket_setsockopt(int sock, int level, int optname,
+                       const void *optval, size_t optlen)
+{
+#ifdef _WIN32
+  /* the winsock setsockopt function has its 4th argument as a
+     const char * */
+  return setsockopt(sock, level, optname, (const char *)optval, optlen);
+#else
+  return setsockopt(sock, level, optname, optval, optlen);
+#endif
+}
+
+static int
+amqp_os_socket_setsockblock(int sock, int block)
+{
+
+#ifdef _WIN32
+  int nonblock = !block;
+  if (NO_ERROR != ioctlsocket(sock, FIONBIO, &nonblock)) {
+    return AMQP_STATUS_SOCKET_ERROR;
+  } else {
+    return AMQP_STATUS_OK;
+  }
+#else
+  long arg;
+
+  if ((arg = fcntl(sock, F_GETFL, NULL)) < 0) {
+     return AMQP_STATUS_SOCKET_ERROR;
+  }
+
+  if (block) {
+    arg &= (~O_NONBLOCK);
+  } else {
+    arg |= O_NONBLOCK;
+  }
+
+  if (fcntl(sock, F_SETFL, arg) < 0) {
+    return AMQP_STATUS_SOCKET_ERROR;
+  }
+
+  return AMQP_STATUS_OK;
+#endif
+}
+
+
+int
+amqp_os_socket_error(void)
+{
+#ifdef _WIN32
+  return WSAGetLastError();
+#else
+  return errno;
+#endif
+}
+
+int
+amqp_os_socket_close(int sockfd)
+{
+#ifdef _WIN32
+  return closesocket(sockfd);
+#else
+  return close(sockfd);
+#endif
+}
+
+ssize_t
+amqp_socket_writev(amqp_socket_t *self, struct iovec *iov, int iovcnt)
+{
+  assert(self);
+  assert(self->klass->writev);
+  return self->klass->writev(self, iov, iovcnt);
+}
+
+ssize_t
+amqp_socket_send(amqp_socket_t *self, const void *buf, size_t len)
+{
+  assert(self);
+  assert(self->klass->send);
+  return self->klass->send(self, buf, len);
+}
+
+ssize_t
+amqp_socket_recv(amqp_socket_t *self, void *buf, size_t len, int flags)
+{
+  assert(self);
+  assert(self->klass->recv);
+  return self->klass->recv(self, buf, len, flags);
+}
+
+int
+amqp_socket_open(amqp_socket_t *self, const char *host, int port)
+{
+  assert(self);
+  assert(self->klass->open);
+  return self->klass->open(self, host, port, NULL);
+}
+
+int
+amqp_socket_open_noblock(amqp_socket_t *self, const char *host, int port, struct timeval *timeout)
+{
+  assert(self);
+  assert(self->klass->open);
+  return self->klass->open(self, host, port, timeout);
+}
+
+int
+amqp_socket_close(amqp_socket_t *self)
+{
+  assert(self);
+  assert(self->klass->close);
+  return self->klass->close(self);
+}
+
+void
+amqp_socket_delete(amqp_socket_t *self)
+{
+  if (self) {
+    assert(self->klass->delete);
+    self->klass->delete(self);
+  }
+}
+
+int
+amqp_socket_get_sockfd(amqp_socket_t *self)
+{
+  assert(self);
+  assert(self->klass->get_sockfd);
+  return self->klass->get_sockfd(self);
+}
+
+int
+amqp_open_socket(char const *hostname,
+                 int portnumber)
+{
+  return amqp_open_socket_noblock(hostname, portnumber, NULL);
+}
+
+int amqp_open_socket_noblock(char const *hostname,
+                     int portnumber,
+                     struct timeval *timeout)
+{
+  struct addrinfo hint;
+  struct addrinfo *address_list;
+  struct addrinfo *addr;
+  char portnumber_string[33];
+  int sockfd = -1;
+  int last_error = AMQP_STATUS_OK;
+  int one = 1; /* for setsockopt */
+  int res;
+  int timer_error;
+  amqp_timer_t timer;
+
+  AMQP_INIT_TIMER(timer)
+
+  if (timeout && (timeout->tv_sec < 0 || timeout->tv_usec < 0 ||
+      INT_MAX < ((uint64_t)timeout->tv_sec * AMQP_MS_PER_S +
+      (uint64_t)timeout->tv_usec / AMQP_US_PER_MS))) {
+    return AMQP_STATUS_INVALID_PARAMETER;
+  }
+
+  last_error = amqp_os_socket_init();
+  if (AMQP_STATUS_OK != last_error) {
+    return last_error;
+  }
+
+  memset(&hint, 0, sizeof(hint));
+  hint.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */
+  hint.ai_socktype = SOCK_STREAM;
+  hint.ai_protocol = IPPROTO_TCP;
+
+  (void)sprintf(portnumber_string, "%d", portnumber);
+
+  last_error = getaddrinfo(hostname, portnumber_string, &hint, &address_list);
+
+  if (0 != last_error) {
+    return AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED;
+  }
+
+  for (addr = address_list; addr; addr = addr->ai_next) {
+    if (-1 != sockfd) {
+      amqp_os_socket_close(sockfd);
+    }
+
+    sockfd = amqp_os_socket_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+
+    if (-1 == sockfd) {
+      last_error = AMQP_STATUS_SOCKET_ERROR;
+      continue;
+    }
+
+#ifdef SO_NOSIGPIPE
+    if (0 != amqp_os_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) {
+      last_error = AMQP_STATUS_SOCKET_ERROR;
+      continue;
+    }
+#endif /* SO_NOSIGPIPE */
+
+    if (0 != amqp_os_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one))) {
+      last_error = AMQP_STATUS_SOCKET_ERROR;
+      continue;
+    }
+
+    if (timeout) {
+      /* Trying to connect with timeout, set socket to non-blocking mode */
+      if (AMQP_STATUS_OK != amqp_os_socket_setsockblock(sockfd, 0)) {
+        last_error = AMQP_STATUS_SOCKET_ERROR;
+        continue;
+      }
+
+      res = connect(sockfd, addr->ai_addr, addr->ai_addrlen);
+
+      if (0 == res) {
+        /* Connected immediately, set to blocking mode again */
+        if (AMQP_STATUS_OK != amqp_os_socket_setsockblock(sockfd, 1)) {
+          last_error = AMQP_STATUS_SOCKET_ERROR;
+          continue;
+        }
+
+        last_error = AMQP_STATUS_OK;
+        break;
+      }
+
+#ifdef _WIN32
+      if (WSAEWOULDBLOCK == amqp_os_socket_error()) {
+#else
+      if (EINPROGRESS == amqp_os_socket_error()) {
+#endif
+
+        while(1) {
+          struct pollfd pfd;
+          int timeout_ms;
+
+          pfd.fd = sockfd;
+          pfd.events = POLLERR | POLLOUT;
+          pfd.revents = 0;
+
+          timer_error = amqp_timer_update(&timer, timeout);
+
+          if (timer_error < 0) {
+            last_error = timer_error;
+            break;
+          }
+
+          timeout_ms = timer.tv.tv_sec * AMQP_MS_PER_S +
+              timer.tv.tv_usec / AMQP_US_PER_MS;
+          /* Win32 requires except_fds to be passed to detect connection
+           * failure. Other platforms only need write_fds, passing except_fds
+           * seems to be harmless otherwise
+           */
+          res = poll(&pfd, 1, timeout_ms);
+
+          if (res > 0) {
+            int result;
+            socklen_t result_len = sizeof(result);
+
+            if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0) {
+              last_error = AMQP_STATUS_SOCKET_ERROR;
+              break;
+            }
+
+            if (result != 0) {
+              last_error = AMQP_STATUS_SOCKET_ERROR;
+              break;
+            }
+
+            /* socket is ready to be written to, set to blocking mode again */
+            if (AMQP_STATUS_OK != amqp_os_socket_setsockblock(sockfd, 1)) {
+              last_error = AMQP_STATUS_SOCKET_ERROR;
+              continue;
+            }
+
+            last_error = AMQP_STATUS_OK;
+            break;
+          } else if (0 == res) {
+            /* Timed out - return */
+            last_error = AMQP_STATUS_TIMEOUT;
+            break;
+          } else if (errno == EINTR) {
+            /* Try again */
+            continue;
+          } else {
+            /* Error connecting */
+            last_error = AMQP_STATUS_SOCKET_ERROR;
+            break;
+          }
+        } /* end while(1) loop */
+
+        if (last_error == AMQP_STATUS_OK
+            || last_error == AMQP_STATUS_TIMEOUT
+            || last_error == AMQP_STATUS_TIMER_FAILURE) {
+          /* Exit for loop on timer errors or when connection established */
+          break;
+        }
+
+      } else {
+        /* Error connecting */
+        last_error = AMQP_STATUS_SOCKET_ERROR;
+        break;
+
+      }
+
+    } else {
+      /* Connect in blocking mode */
+      if (0 != connect(sockfd, addr->ai_addr, addr->ai_addrlen)) {
+        last_error = AMQP_STATUS_SOCKET_ERROR;
+        continue;
+      } else {
+        last_error = AMQP_STATUS_OK;
+        break;
+      }
+    }
+  }
+
+  freeaddrinfo(address_list);
+  if (last_error != AMQP_STATUS_OK) {
+    if (-1 != sockfd) {
+      amqp_os_socket_close(sockfd);
+    }
+
+    return last_error;
+  }
+
+  return sockfd;
+}
+
+int amqp_send_header(amqp_connection_state_t state)
+{
+  static const uint8_t header[8] = { 'A', 'M', 'Q', 'P', 0,
+                                     AMQP_PROTOCOL_VERSION_MAJOR,
+                                     AMQP_PROTOCOL_VERSION_MINOR,
+                                     AMQP_PROTOCOL_VERSION_REVISION
+                                   };
+  return amqp_socket_send(state->socket, header, sizeof(header));
+}
+
+static amqp_bytes_t sasl_method_name(amqp_sasl_method_enum method)
+{
+  amqp_bytes_t res;
+
+  switch (method) {
+  case AMQP_SASL_METHOD_PLAIN:
+    res.bytes = "PLAIN";
+    res.len = 5;
+    break;
+
+  default:
+    amqp_abort("Invalid SASL method: %d", (int) method);
+  }
+
+  return res;
+}
+
+static amqp_bytes_t sasl_response(amqp_pool_t *pool,
+                                  amqp_sasl_method_enum method,
+                                  va_list args)
+{
+  amqp_bytes_t response;
+
+  switch (method) {
+  case AMQP_SASL_METHOD_PLAIN: {
+    char *username = va_arg(args, char *);
+    size_t username_len = strlen(username);
+    char *password = va_arg(args, char *);
+    size_t password_len = strlen(password);
+    char *response_buf;
+
+    amqp_pool_alloc_bytes(pool, strlen(username) + strlen(password) + 2, &response);
+    if (response.bytes == NULL)
+      /* We never request a zero-length block, because of the +2
+         above, so a NULL here really is ENOMEM. */
+    {
+      return response;
+    }
+
+    response_buf = response.bytes;
+    response_buf[0] = 0;
+    memcpy(response_buf + 1, username, username_len);
+    response_buf[username_len + 1] = 0;
+    memcpy(response_buf + username_len + 2, password, password_len);
+    break;
+  }
+  default:
+    amqp_abort("Invalid SASL method: %d", (int) method);
+  }
+
+  return response;
+}
+
+amqp_boolean_t amqp_frames_enqueued(amqp_connection_state_t state)
+{
+  return (state->first_queued_frame != NULL);
+}
+
+/*
+ * Check to see if we have data in our buffer. If this returns 1, we
+ * will avoid an immediate blocking read in amqp_simple_wait_frame.
+ */
+amqp_boolean_t amqp_data_in_buffer(amqp_connection_state_t state)
+{
+  return (state->sock_inbound_offset < state->sock_inbound_limit);
+}
+
+static int consume_one_frame(amqp_connection_state_t state, amqp_frame_t *decoded_frame)
+{
+  int res;
+
+  amqp_bytes_t buffer;
+  buffer.len = state->sock_inbound_limit - state->sock_inbound_offset;
+  buffer.bytes = ((char *) state->sock_inbound_buffer.bytes) + state->sock_inbound_offset;
+
+  res = amqp_handle_input(state, buffer, decoded_frame);
+  if (res < 0) {
+    return res;
+  }
+
+  state->sock_inbound_offset += res;
+
+  return AMQP_STATUS_OK;
+}
+
+
+static int recv_with_timeout(amqp_connection_state_t state, uint64_t start, struct timeval *timeout)
+{
+  int res;
+
+  if (timeout) {
+    int fd;
+
+    fd = amqp_get_sockfd(state);
+    if (-1 == fd) {
+      return AMQP_STATUS_CONNECTION_CLOSED;
+    }
+
+    if (INT_MAX < (uint64_t)timeout->tv_sec * AMQP_MS_PER_S +
+        (uint64_t)timeout->tv_usec / AMQP_US_PER_MS) {
+      return AMQP_STATUS_INVALID_PARAMETER;
+    }
+
+    while (1) {
+      struct pollfd pfd;
+      int timeout_ms;
+
+      pfd.fd = fd;
+      pfd.events = POLLIN;
+      pfd.revents = 0;
+
+      timeout_ms = timeout->tv_sec * AMQP_MS_PER_S +
+          timeout->tv_usec / AMQP_US_PER_MS;
+
+      res = poll(&pfd, 1, timeout_ms);
+
+      if (0 < res) {
+        break;
+      } else if (0 == res) {
+        return AMQP_STATUS_TIMEOUT;
+      } else if (-1 == res) {
+        if (EINTR == errno) {
+          if (timeout) {
+            uint64_t end_timestamp;
+            uint64_t time_left;
+            uint64_t current_timestamp = amqp_get_monotonic_timestamp();
+            if (0 == current_timestamp) {
+              return AMQP_STATUS_TIMER_FAILURE;
+            }
+            end_timestamp = start +
+              (uint64_t)timeout->tv_sec * AMQP_NS_PER_S +
+              (uint64_t)timeout->tv_usec * AMQP_NS_PER_US;
+            if (current_timestamp > end_timestamp) {
+              return AMQP_STATUS_TIMEOUT;
+            }
+
+            time_left = end_timestamp - current_timestamp;
+
+            timeout->tv_sec = time_left / AMQP_NS_PER_S;
+            timeout->tv_usec = (time_left % AMQP_NS_PER_S) / AMQP_NS_PER_US;
+          }
+          continue;
+        }
+        return AMQP_STATUS_SOCKET_ERROR;
+      }
+    }
+  }
+
+  res = amqp_socket_recv(state->socket, state->sock_inbound_buffer.bytes,
+                         state->sock_inbound_buffer.len, 0);
+
+  if (res < 0) {
+    return res;
+  }
+
+  state->sock_inbound_limit = res;
+  state->sock_inbound_offset = 0;
+
+  if (amqp_heartbeat_enabled(state)) {
+    uint64_t current_time = amqp_get_monotonic_timestamp();
+    if (0 == current_time) {
+      return AMQP_STATUS_TIMER_FAILURE;
+    }
+    state->next_recv_heartbeat = amqp_calc_next_recv_heartbeat(state, current_time);
+  }
+
+  return AMQP_STATUS_OK;
+}
+
+int amqp_try_recv(amqp_connection_state_t state, uint64_t current_time)
+{
+  struct timeval tv;
+
+  while (amqp_data_in_buffer(state)) {
+    amqp_frame_t frame;
+    int res = consume_one_frame(state, &frame);
+
+    if (AMQP_STATUS_OK != res) {
+      return res;
+    }
+
+    if (frame.frame_type != 0) {
+      amqp_pool_t *channel_pool;
+      amqp_frame_t *frame_copy;
+      amqp_link_t *link;
+
+      channel_pool = amqp_get_or_create_channel_pool(state, frame.channel);
+      if (NULL == channel_pool) {
+        return AMQP_STATUS_NO_MEMORY;
+      }
+
+      frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t));
+      link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t));
+
+      if (frame_copy == NULL || link == NULL) {
+        return AMQP_STATUS_NO_MEMORY;
+      }
+
+      *frame_copy = frame;
+
+      link->next = NULL;
+      link->data = frame_copy;
+
+      if (state->last_queued_frame == NULL) {
+        state->first_queued_frame = link;
+      } else {
+        state->last_queued_frame->next = link;
+      }
+      state->last_queued_frame = link;
+    }
+  }
+
+  memset(&tv, 0, sizeof(struct timeval));
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+
+  return recv_with_timeout(state, current_time, &tv);
+}
+
+static int wait_frame_inner(amqp_connection_state_t state,
+                            amqp_frame_t *decoded_frame,
+                            struct timeval *timeout)
+{
+  uint64_t current_timestamp = 0;
+  uint64_t timeout_timestamp = 0;
+  uint64_t next_timestamp = 0;
+  struct timeval tv;
+  struct timeval *tvp = NULL;
+
+  if (timeout && (timeout->tv_sec < 0 || timeout->tv_usec < 0)) {
+    return AMQP_STATUS_INVALID_PARAMETER;
+  }
+
+  while (1) {
+    int res;
+
+    while (amqp_data_in_buffer(state)) {
+      res = consume_one_frame(state, decoded_frame);
+
+      if (AMQP_STATUS_OK != res) {
+        return res;
+      }
+
+      if (AMQP_FRAME_HEARTBEAT == decoded_frame->frame_type) {
+        amqp_maybe_release_buffers_on_channel(state, 0);
+        continue;
+      }
+
+      if (decoded_frame->frame_type != 0) {
+        /* Complete frame was read. Return it. */
+        return AMQP_STATUS_OK;
+      }
+    }
+
+beginrecv:
+    if (timeout || amqp_heartbeat_enabled(state)) {
+      uint64_t ns_until_next_timeout;
+
+      current_timestamp = amqp_get_monotonic_timestamp();
+      if (0 == current_timestamp) {
+        return AMQP_STATUS_TIMER_FAILURE;
+      }
+
+      if (amqp_heartbeat_enabled(state) && current_timestamp > state->next_send_heartbeat) {
+        amqp_frame_t heartbeat;
+        heartbeat.channel = 0;
+        heartbeat.frame_type = AMQP_FRAME_HEARTBEAT;
+
+        res = amqp_send_frame(state, &heartbeat);
+        if (AMQP_STATUS_OK != res) {
+          return res;
+        }
+
+        current_timestamp = amqp_get_monotonic_timestamp();
+        if (0 == current_timestamp) {
+          return AMQP_STATUS_TIMER_FAILURE;
+        }
+      }
+
+      if (timeout) {
+        if (0 == timeout_timestamp) {
+          timeout_timestamp = current_timestamp +
+            (uint64_t)timeout->tv_sec * AMQP_NS_PER_S +
+            (uint64_t)timeout->tv_usec * AMQP_NS_PER_US;
+        }
+
+        if (current_timestamp > timeout_timestamp) {
+          return AMQP_STATUS_TIMEOUT;
+        }
+      }
+
+
+      if (amqp_heartbeat_enabled(state)) {
+        if (current_timestamp > state->next_recv_heartbeat) {
+          state->next_recv_heartbeat = current_timestamp;
+        }
+        next_timestamp = (state->next_recv_heartbeat < state->next_send_heartbeat ?
+            state->next_recv_heartbeat :
+            state->next_send_heartbeat);
+        if (timeout) {
+          next_timestamp = (timeout_timestamp < next_timestamp ?
+              timeout_timestamp : next_timestamp);
+        }
+      } else if (timeout) {
+        next_timestamp = timeout_timestamp;
+      } else {
+        amqp_abort("Internal error: both timeout == NULL && state->heartbeat == 0");
+      }
+
+      ns_until_next_timeout = next_timestamp - current_timestamp;
+
+      memset(&tv, 0, sizeof(struct timeval));
+      tv.tv_sec = ns_until_next_timeout / AMQP_NS_PER_S;
+      tv.tv_usec = (ns_until_next_timeout % AMQP_NS_PER_S) / AMQP_NS_PER_US;
+
+      tvp = &tv;
+    }
+
+    res = recv_with_timeout(state, current_timestamp, tvp);
+
+    if (AMQP_STATUS_TIMEOUT == res) {
+      if (next_timestamp == state->next_recv_heartbeat) {
+        amqp_socket_close(state->socket);
+        return AMQP_STATUS_HEARTBEAT_TIMEOUT;
+      } else if (next_timestamp == timeout_timestamp) {
+        return AMQP_STATUS_TIMEOUT;
+      } else if (next_timestamp == state->next_send_heartbeat) {
+        /* send heartbeat happens before we do recv_with_timeout */
+        goto beginrecv;
+      } else {
+        amqp_abort("Internal error: unable to determine timeout reason");
+      }
+    } else if (AMQP_STATUS_OK != res) {
+      return res;
+    }
+  }
+}
+
+static amqp_link_t * amqp_create_link_for_frame(amqp_connection_state_t state, amqp_frame_t *frame)
+{
+  amqp_link_t *link;
+  amqp_frame_t *frame_copy;
+
+  amqp_pool_t *channel_pool = amqp_get_or_create_channel_pool(state, frame->channel);
+
+  if (NULL == channel_pool) {
+    return NULL;
+  }
+
+  link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t));
+  frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t));
+
+  if (NULL == link || NULL == frame_copy) {
+    return NULL;
+  }
+
+  *frame_copy = *frame;
+  link->data = frame_copy;
+
+  return link;
+}
+
+int amqp_queue_frame(amqp_connection_state_t state, amqp_frame_t *frame)
+{
+  amqp_link_t *link = amqp_create_link_for_frame(state, frame);
+  if (NULL == link) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+
+  if (NULL == state->first_queued_frame) {
+    state->first_queued_frame = link;
+  } else {
+    state->last_queued_frame->next = link;
+  }
+
+  link->next = NULL;
+  state->last_queued_frame = link;
+
+  return AMQP_STATUS_OK;
+}
+
+int amqp_put_back_frame(amqp_connection_state_t state, amqp_frame_t *frame)
+{
+  amqp_link_t *link = amqp_create_link_for_frame(state, frame);
+  if (NULL == link) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+
+  if (NULL == state->first_queued_frame) {
+    state->first_queued_frame = link;
+    state->last_queued_frame = link;
+    link->next = NULL;
+  } else {
+    link->next = state->first_queued_frame;
+    state->first_queued_frame = link;
+  }
+
+  return AMQP_STATUS_OK;
+}
+
+int amqp_simple_wait_frame_on_channel(amqp_connection_state_t state,
+                                      amqp_channel_t channel,
+                                      amqp_frame_t *decoded_frame)
+{
+  amqp_frame_t *frame_ptr;
+  amqp_link_t *cur;
+  int res;
+
+  for (cur = state->first_queued_frame; NULL != cur; cur = cur->next) {
+    frame_ptr = cur->data;
+
+    if (channel == frame_ptr->channel) {
+      state->first_queued_frame = cur->next;
+      if (NULL == state->first_queued_frame) {
+        state->last_queued_frame = NULL;
+      }
+
+      *decoded_frame = *frame_ptr;
+
+      return AMQP_STATUS_OK;
+    }
+  }
+
+  while (1) {
+    res = wait_frame_inner(state, decoded_frame, NULL);
+
+    if (AMQP_STATUS_OK != res) {
+      return res;
+    }
+
+    if (channel == decoded_frame->channel) {
+      return AMQP_STATUS_OK;
+    } else {
+      res = amqp_queue_frame(state, decoded_frame);
+      if (res != AMQP_STATUS_OK) {
+        return res;
+      }
+    }
+  }
+}
+
+int amqp_simple_wait_frame(amqp_connection_state_t state,
+                           amqp_frame_t *decoded_frame)
+{
+  return amqp_simple_wait_frame_noblock(state, decoded_frame, NULL);
+}
+
+int amqp_simple_wait_frame_noblock(amqp_connection_state_t state,
+                                   amqp_frame_t *decoded_frame,
+                                   struct timeval *timeout)
+{
+  if (state->first_queued_frame != NULL) {
+    amqp_frame_t *f = (amqp_frame_t *) state->first_queued_frame->data;
+    state->first_queued_frame = state->first_queued_frame->next;
+    if (state->first_queued_frame == NULL) {
+      state->last_queued_frame = NULL;
+    }
+    *decoded_frame = *f;
+    return AMQP_STATUS_OK;
+  } else {
+    return wait_frame_inner(state, decoded_frame, timeout);
+  }
+}
+
+int amqp_simple_wait_method(amqp_connection_state_t state,
+                            amqp_channel_t expected_channel,
+                            amqp_method_number_t expected_method,
+                            amqp_method_t *output)
+{
+  amqp_frame_t frame;
+  int res = amqp_simple_wait_frame(state, &frame);
+  if (AMQP_STATUS_OK != res) {
+    return res;
+  }
+
+  if (frame.channel != expected_channel
+      || frame.frame_type != AMQP_FRAME_METHOD
+      || frame.payload.method.id != expected_method) {
+    amqp_socket_close(state->socket);
+    return AMQP_STATUS_WRONG_METHOD;
+  }
+  *output = frame.payload.method;
+  return AMQP_STATUS_OK;
+}
+
+int amqp_send_method(amqp_connection_state_t state,
+                     amqp_channel_t channel,
+                     amqp_method_number_t id,
+                     void *decoded)
+{
+  amqp_frame_t frame;
+
+  frame.frame_type = AMQP_FRAME_METHOD;
+  frame.channel = channel;
+  frame.payload.method.id = id;
+  frame.payload.method.decoded = decoded;
+  return amqp_send_frame(state, &frame);
+}
+
+static int amqp_id_in_reply_list( amqp_method_number_t expected, amqp_method_number_t *list )
+{
+  while ( *list != 0 ) {
+    if ( *list == expected ) {
+      return 1;
+    }
+    list++;
+  }
+  return 0;
+}
+
+amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state,
+                                 amqp_channel_t channel,
+                                 amqp_method_number_t request_id,
+                                 amqp_method_number_t *expected_reply_ids,
+                                 void *decoded_request_method)
+{
+  int status;
+  amqp_rpc_reply_t result;
+
+  memset(&result, 0, sizeof(result));
+
+  status = amqp_send_method(state, channel, request_id, decoded_request_method);
+  if (status < 0) {
+    result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+    result.library_error = status;
+    return result;
+  }
+
+  {
+    amqp_frame_t frame;
+
+retry:
+    status = wait_frame_inner(state, &frame, NULL);
+    if (status < 0) {
+      result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+      result.library_error = status;
+      return result;
+    }
+
+    /*
+     * We store the frame for later processing unless it's something
+     * that directly affects us here, namely a method frame that is
+     * either
+     *  - on the channel we want, and of the expected type, or
+     *  - on the channel we want, and a channel.close frame, or
+     *  - on channel zero, and a connection.close frame.
+     */
+    if (!((frame.frame_type == AMQP_FRAME_METHOD)
+          && (
+            ((frame.channel == channel)
+             && (amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids)
+                 || (frame.payload.method.id == AMQP_CHANNEL_CLOSE_METHOD)))
+            ||
+            ((frame.channel == 0)
+             && (frame.payload.method.id == AMQP_CONNECTION_CLOSE_METHOD))
+          )
+         )) {
+      amqp_pool_t *channel_pool;
+      amqp_frame_t *frame_copy;
+      amqp_link_t *link;
+
+      channel_pool = amqp_get_or_create_channel_pool(state, frame.channel);
+      if (NULL == channel_pool) {
+        result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+        result.library_error = AMQP_STATUS_NO_MEMORY;
+        return result;
+      }
+
+      frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t));
+      link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t));
+
+      if (frame_copy == NULL || link == NULL) {
+        result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+        result.library_error = AMQP_STATUS_NO_MEMORY;
+        return result;
+      }
+
+      *frame_copy = frame;
+
+      link->next = NULL;
+      link->data = frame_copy;
+
+      if (state->last_queued_frame == NULL) {
+        state->first_queued_frame = link;
+      } else {
+        state->last_queued_frame->next = link;
+      }
+      state->last_queued_frame = link;
+
+      goto retry;
+    }
+
+    result.reply_type = (amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids))
+                        ? AMQP_RESPONSE_NORMAL
+                        : AMQP_RESPONSE_SERVER_EXCEPTION;
+
+    result.reply = frame.payload.method;
+    return result;
+  }
+}
+
+void *amqp_simple_rpc_decoded(amqp_connection_state_t state,
+                              amqp_channel_t channel,
+                              amqp_method_number_t request_id,
+                              amqp_method_number_t reply_id,
+                              void *decoded_request_method)
+{
+  amqp_method_number_t replies[2];
+
+  replies[0] = reply_id;
+  replies[1] = 0;
+
+  state->most_recent_api_result = amqp_simple_rpc(state, channel,
+                                  request_id, replies,
+                                  decoded_request_method);
+  if (state->most_recent_api_result.reply_type == AMQP_RESPONSE_NORMAL) {
+    return state->most_recent_api_result.reply.decoded;
+  } else {
+    return NULL;
+  }
+}
+
+amqp_rpc_reply_t amqp_get_rpc_reply(amqp_connection_state_t state)
+{
+  return state->most_recent_api_result;
+}
+
+
+static int amqp_table_contains_entry(const amqp_table_t *table,
+                                     const amqp_table_entry_t *entry)
+{
+  int i;
+  amqp_table_entry_t *current_entry;
+
+  assert(table != NULL);
+  assert(entry != NULL);
+
+  current_entry = table->entries;
+
+  for (i = 0; i < table->num_entries; ++i, ++current_entry) {
+    if (0 == amqp_table_entry_cmp(current_entry, entry)) {
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+static amqp_rpc_reply_t amqp_login_inner(amqp_connection_state_t state,
+    char const *vhost,
+    int channel_max,
+    int frame_max,
+    int heartbeat,
+    const amqp_table_t *client_properties,
+    amqp_sasl_method_enum sasl_method,
+    va_list vl)
+{
+  int res;
+  amqp_method_t method;
+  int server_frame_max;
+  uint16_t server_channel_max;
+  uint16_t server_heartbeat;
+  amqp_rpc_reply_t result;
+
+  res = amqp_send_header(state);
+  if (AMQP_STATUS_OK != res) {
+    goto error_res;
+  }
+
+  res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD,
+                                &method);
+  if (res < 0) {
+    goto error_res;
+  }
+
+  {
+    amqp_connection_start_t *s = (amqp_connection_start_t *) method.decoded;
+    if ((s->version_major != AMQP_PROTOCOL_VERSION_MAJOR)
+        || (s->version_minor != AMQP_PROTOCOL_VERSION_MINOR)) {
+      res = AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION;
+      goto error_res;
+    }
+
+    res = amqp_table_clone(&s->server_properties, &state->server_properties,
+                           &state->properties_pool);
+
+    if (AMQP_STATUS_OK != res) {
+      goto error_res;
+    }
+
+    /* TODO: check that our chosen SASL mechanism is in the list of
+       acceptable mechanisms. Or even let the application choose from
+       the list! */
+  }
+
+  {
+    amqp_table_entry_t default_properties[5];
+    amqp_table_t default_table;
+    amqp_connection_start_ok_t s;
+    amqp_pool_t *channel_pool;
+    amqp_bytes_t response_bytes;
+
+    channel_pool = amqp_get_or_create_channel_pool(state, 0);
+    if (NULL == channel_pool) {
+      res = AMQP_STATUS_NO_MEMORY;
+      goto error_res;
+    }
+
+    response_bytes = sasl_response(channel_pool,
+                     sasl_method, vl);
+    if (response_bytes.bytes == NULL) {
+      res = AMQP_STATUS_NO_MEMORY;
+      goto error_res;
+    }
+
+    default_properties[0].key = amqp_cstring_bytes("product");
+    default_properties[0].value.kind = AMQP_FIELD_KIND_UTF8;
+    default_properties[0].value.value.bytes =
+      amqp_cstring_bytes("rabbitmq-c");
+
+    /* version */
+    default_properties[1].key = amqp_cstring_bytes("version");
+    default_properties[1].value.kind = AMQP_FIELD_KIND_UTF8;
+    default_properties[1].value.value.bytes =
+        amqp_cstring_bytes(AMQP_VERSION_STRING);
+
+    /* platform */
+    default_properties[2].key = amqp_cstring_bytes("platform");
+    default_properties[2].value.kind = AMQP_FIELD_KIND_UTF8;
+    default_properties[2].value.value.bytes =
+        amqp_cstring_bytes(AMQ_PLATFORM);
+
+    /* copyright */
+    default_properties[3].key = amqp_cstring_bytes("copyright");
+    default_properties[3].value.kind = AMQP_FIELD_KIND_UTF8;
+    default_properties[3].value.value.bytes =
+        amqp_cstring_bytes(AMQ_COPYRIGHT);
+
+    default_properties[4].key = amqp_cstring_bytes("information");
+    default_properties[4].value.kind = AMQP_FIELD_KIND_UTF8;
+    default_properties[4].value.value.bytes =
+      amqp_cstring_bytes("See https://github.com/alanxz/rabbitmq-c");
+
+    default_table.entries = default_properties;
+    default_table.num_entries = sizeof(default_properties) / sizeof(amqp_table_entry_t);
+
+    if (0 == client_properties->num_entries) {
+      s.client_properties = default_table;
+    } else {
+      /* Merge provided properties with our default properties:
+       * - Copy default properties.
+       * - Any provided property that doesn't have the same key as a default
+       *   property is also copied.
+       *
+       * TODO: if one of the default properties is a capabilities table, we will
+       * need to figure out how to merge this if the user provides a capabilites
+       * table
+       */
+      int i;
+      amqp_table_entry_t *current_entry;
+
+      s.client_properties.entries = amqp_pool_alloc(channel_pool,
+                                    sizeof(amqp_table_entry_t) * (default_table.num_entries + client_properties->num_entries));
+      if (NULL == s.client_properties.entries) {
+        res = AMQP_STATUS_NO_MEMORY;
+        goto error_res;
+      }
+      s.client_properties.num_entries = 0;
+
+      current_entry = s.client_properties.entries;
+
+      for (i = 0; i < default_table.num_entries; ++i) {
+        memcpy(current_entry, &default_table.entries[i], sizeof(amqp_table_entry_t));
+        s.client_properties.num_entries += 1;
+        ++current_entry;
+      }
+
+      for (i = 0; i < client_properties->num_entries; ++i) {
+        if (amqp_table_contains_entry(&default_table, &client_properties->entries[i])) {
+          continue;
+        }
+        memcpy(current_entry, &client_properties->entries[i], sizeof(amqp_table_entry_t));
+        s.client_properties.num_entries += 1;
+        ++current_entry;
+      }
+    }
+
+    s.mechanism = sasl_method_name(sasl_method);
+    s.response = response_bytes;
+    s.locale.bytes = "en_US";
+    s.locale.len = 5;
+
+    res = amqp_send_method(state, 0, AMQP_CONNECTION_START_OK_METHOD, &s);
+    if (res < 0) {
+      goto error_res;
+    }
+  }
+
+  amqp_release_buffers(state);
+
+  res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_TUNE_METHOD,
+                                &method);
+  if (res < 0) {
+    goto error_res;
+  }
+
+  {
+    amqp_connection_tune_t *s = (amqp_connection_tune_t *) method.decoded;
+    server_channel_max = s->channel_max;
+    server_frame_max = s->frame_max;
+    server_heartbeat = s->heartbeat;
+  }
+
+  if (server_channel_max != 0 && server_channel_max < channel_max) {
+    channel_max = server_channel_max;
+  } else if (server_channel_max == 0 && channel_max == 0) {
+    channel_max = UINT16_MAX;
+  }
+
+  if (server_frame_max != 0 && server_frame_max < frame_max) {
+    frame_max = server_frame_max;
+  }
+
+  if (server_heartbeat != 0 && server_heartbeat < heartbeat) {
+    heartbeat = server_heartbeat;
+  }
+
+  res = amqp_tune_connection(state, channel_max, frame_max, heartbeat);
+  if (res < 0) {
+    goto error_res;
+  }
+
+  {
+    amqp_connection_tune_ok_t s;
+    s.frame_max = frame_max;
+    s.channel_max = channel_max;
+    s.heartbeat = heartbeat;
+
+    res = amqp_send_method(state, 0, AMQP_CONNECTION_TUNE_OK_METHOD, &s);
+    if (res < 0) {
+      goto error_res;
+    }
+  }
+
+  amqp_release_buffers(state);
+
+  {
+    amqp_method_number_t replies[] = { AMQP_CONNECTION_OPEN_OK_METHOD, 0 };
+    amqp_connection_open_t s;
+    s.virtual_host = amqp_cstring_bytes(vhost);
+    s.capabilities.len = 0;
+    s.capabilities.bytes = NULL;
+    s.insist = 1;
+
+    result = amqp_simple_rpc(state,
+                             0,
+                             AMQP_CONNECTION_OPEN_METHOD,
+                             (amqp_method_number_t *) &replies,
+                             &s);
+    if (result.reply_type != AMQP_RESPONSE_NORMAL) {
+      goto out;
+    }
+  }
+
+  result.reply_type = AMQP_RESPONSE_NORMAL;
+  result.reply.id = 0;
+  result.reply.decoded = NULL;
+  result.library_error = 0;
+
+out:
+  amqp_maybe_release_buffers(state);
+  return result;
+
+error_res:
+  result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
+  result.reply.id = 0;
+  result.reply.decoded = NULL;
+  result.library_error = res;
+
+  goto out;
+}
+
+amqp_rpc_reply_t amqp_login(amqp_connection_state_t state,
+                            char const *vhost,
+                            int channel_max,
+                            int frame_max,
+                            int heartbeat,
+                            amqp_sasl_method_enum sasl_method,
+                            ...)
+{
+  va_list vl;
+  amqp_rpc_reply_t ret;
+
+  va_start(vl, sasl_method);
+
+  ret = amqp_login_inner(state, vhost, channel_max, frame_max, heartbeat,
+                         &amqp_empty_table, sasl_method, vl);
+
+  va_end(vl);
+
+  return ret;
+}
+
+amqp_rpc_reply_t amqp_login_with_properties(amqp_connection_state_t state,
+    char const *vhost,
+    int channel_max,
+    int frame_max,
+    int heartbeat,
+    const amqp_table_t *client_properties,
+    amqp_sasl_method_enum sasl_method,
+    ...)
+{
+  va_list vl;
+  amqp_rpc_reply_t ret;
+
+  va_start(vl, sasl_method);
+
+  ret = amqp_login_inner(state, vhost, channel_max, frame_max, heartbeat,
+                         client_properties, sasl_method, vl);
+
+  va_end(vl);
+
+  return ret;
+}
diff --git a/modules/kazoo/deps/amqp_socket.h b/modules/kazoo/deps/amqp_socket.h
new file mode 100644
index 0000000..315c4df
--- /dev/null
+++ b/modules/kazoo/deps/amqp_socket.h
@@ -0,0 +1,195 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
+ * All Rights Reserved.
+ *
+ * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael
+ * Steinert. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * An abstract socket interface.
+ */
+
+#ifndef AMQP_SOCKET_H
+#define AMQP_SOCKET_H
+
+#include "amqp_private.h"
+
+AMQP_BEGIN_DECLS
+
+int
+amqp_os_socket_error(void);
+
+int
+amqp_os_socket_close(int sockfd);
+
+/* Socket callbacks. */
+typedef ssize_t (*amqp_socket_writev_fn)(void *, struct iovec *, int);
+typedef ssize_t (*amqp_socket_send_fn)(void *, const void *, size_t);
+typedef ssize_t (*amqp_socket_recv_fn)(void *, void *, size_t, int);
+typedef int (*amqp_socket_open_fn)(void *, const char *, int, struct timeval *);
+typedef int (*amqp_socket_close_fn)(void *);
+typedef int (*amqp_socket_get_sockfd_fn)(void *);
+typedef void (*amqp_socket_delete_fn)(void *);
+
+/** V-table for amqp_socket_t */
+struct amqp_socket_class_t {
+  amqp_socket_writev_fn writev;
+  amqp_socket_send_fn send;
+  amqp_socket_recv_fn recv;
+  amqp_socket_open_fn open;
+  amqp_socket_close_fn close;
+  amqp_socket_get_sockfd_fn get_sockfd;
+  amqp_socket_delete_fn delete;
+};
+
+/** Abstract base class for amqp_socket_t */
+struct amqp_socket_t_ {
+  const struct amqp_socket_class_t *klass;
+};
+
+
+#ifdef _WIN32
+/* WinSock2 calls iovec WSABUF with different parameter names.
+ * this is really a WSABUF with different names
+ */
+struct iovec {
+  u_long iov_len;
+  char FAR *iov_base;
+};
+#endif
+
+
+/**
+ * Set set the socket object for a connection
+ *
+ * This assigns a socket object to the connection, closing and deleting any
+ * existing socket
+ *
+ * \param [in] state The connection object to add the socket to
+ * \param [in] socket The socket object to assign to the connection
+ */
+void
+amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket);
+
+/**
+ * Write to a socket.
+ *
+ * This function wraps writev(2) functionality.
+ *
+ * This function will only reutrn on error, or when all of the bytes referred
+ * to in iov have been sent. NOTE: this function may modify the iov struct.
+ *
+ * \param [in,out] self A socket object.
+ * \param [in] iov One or more data vecors.
+ * \param [in] iovcnt The number of vectors in \e iov.
+ *
+ * \return AMQP_STATUS_OK on success. amqp_status_enum value otherwise
+ */
+ssize_t
+amqp_socket_writev(amqp_socket_t *self, struct iovec *iov, int iovcnt);
+
+/**
+ * Send a message from a socket.
+ *
+ * This function wraps send(2) functionality.
+ *
+ * This function will only return on error, or when all of the bytes in buf
+ * have been sent, or when an error occurs.
+ *
+ * \param [in,out] self A socket object.
+ * \param [in] buf A buffer to read from.
+ * \param [in] len The number of bytes in \e buf.
+ *
+ * \return AMQP_STATUS_OK on success. amqp_status_enum value otherwise
+ */
+ssize_t
+amqp_socket_send(amqp_socket_t *self, const void *buf, size_t len);
+
+/**
+ * Receive a message from a socket.
+ *
+ * This function wraps recv(2) functionality.
+ *
+ * \param [in,out] self A socket object.
+ * \param [out] buf A buffer to write to.
+ * \param [in] len The number of bytes at \e buf.
+ * \param [in] flags Receive flags, implementation specific.
+ *
+ * \return The number of bytes received, or < 0 on error (\ref amqp_status_enum)
+ */
+ssize_t
+amqp_socket_recv(amqp_socket_t *self, void *buf, size_t len, int flags);
+
+/**
+ * Close a socket connection and free resources.
+ *
+ * This function closes a socket connection and releases any resources used by
+ * the object. After calling this function the specified socket should no
+ * longer be referenced.
+ *
+ * \param [in,out] self A socket object.
+ *
+ * \return Zero upon success, non-zero otherwise.
+ */
+int
+amqp_socket_close(amqp_socket_t *self);
+
+/**
+ * Destroy a socket object
+ *
+ * \param [in] self the socket object to delete
+ */
+void
+amqp_socket_delete(amqp_socket_t *self);
+
+/**
+ * Open a socket connection.
+ *
+ * This function opens a socket connection returned from amqp_tcp_socket_new()
+ * or amqp_ssl_socket_new(). This function should be called after setting
+ * socket options and prior to assigning the socket to an AMQP connection with
+ * amqp_set_socket().
+ *
+ * \param [in] host Connect to this host.
+ * \param [in] port Connect on this remote port.
+ * \param [in] timeout Max allowed time to spent on opening. If NULL - run in blocking mode
+ *
+ * \return File descriptor upon success, non-zero negative error code otherwise.
+ */
+int
+amqp_open_socket_noblock(char const *hostname, int portnumber, struct timeval *timeout);
+
+int
+amqp_queue_frame(amqp_connection_state_t state, amqp_frame_t *frame);
+
+int
+amqp_put_back_frame(amqp_connection_state_t state, amqp_frame_t *frame);
+
+int
+amqp_simple_wait_frame_on_channel(amqp_connection_state_t state,
+                                  amqp_channel_t channel,
+                                  amqp_frame_t *decoded_frame);
+
+AMQP_END_DECLS
+
+#endif /* AMQP_SOCKET_H */
diff --git a/modules/kazoo/deps/amqp_ssl_socket.h b/modules/kazoo/deps/amqp_ssl_socket.h
new file mode 100644
index 0000000..21a346a
--- /dev/null
+++ b/modules/kazoo/deps/amqp_ssl_socket.h
@@ -0,0 +1,168 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/** \file */
+/*
+ * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
+ * All Rights Reserved.
+ *
+ * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael
+ * Steinert. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef AMQP_SSL_H
+#define AMQP_SSL_H
+
+#include <amqp.h>
+
+AMQP_BEGIN_DECLS
+
+/**
+ * Create a new SSL/TLS socket object.
+ *
+ * The returned socket object is owned by the \ref amqp_connection_state_t object
+ * and will be destroyed when the state object is destroyed or a new socket
+ * object is created.
+ *
+ * If the socket object creation fails, the \ref amqp_connection_state_t object
+ * will not be changed.
+ *
+ * The object returned by this function can be retrieved from the
+ * amqp_connection_state_t object later using the amqp_get_socket() function.
+ *
+ * Calling this function may result in the underlying SSL library being initialized.
+ * \sa amqp_set_initialize_ssl_library()
+ *
+ * \param [in,out] state The connection object that owns the SSL/TLS socket
+ * \return A new socket object or NULL if an error occurred.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_socket_t *
+AMQP_CALL
+amqp_ssl_socket_new(amqp_connection_state_t state);
+
+/**
+ * Set the CA certificate.
+ *
+ * \param [in,out] self An SSL/TLS socket object.
+ * \param [in] cacert Path to the CA cert file in PEM format.
+ *
+ * \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on
+ *  failure.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_ssl_socket_set_cacert(amqp_socket_t *self,
+                           const char *cacert);
+
+/**
+ * Set the client key.
+ *
+ * \param [in,out] self An SSL/TLS socket object.
+ * \param [in] cert Path to the client certificate in PEM foramt.
+ * \param [in] key Path to the client key in PEM format.
+ *
+ * \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on
+ *  failure.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_ssl_socket_set_key(amqp_socket_t *self,
+                        const char *cert,
+                        const char *key);
+
+/**
+ * Set the client key from a buffer.
+ *
+ * \param [in,out] self An SSL/TLS socket object.
+ * \param [in] cert Path to the client certificate in PEM foramt.
+ * \param [in] key A buffer containing client key in PEM format.
+ * \param [in] n The length of the buffer.
+ *
+ * \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on
+ *  failure.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_ssl_socket_set_key_buffer(amqp_socket_t *self,
+                               const char *cert,
+                               const void *key,
+                               size_t n);
+
+/**
+ * Enable or disable peer verification.
+ *
+ * If peer verification is enabled then the common name in the server
+ * certificate must match the server name. Peer verification is enabled by
+ * default.
+ *
+ * \param [in,out] self An SSL/TLS socket object.
+ * \param [in] verify Enable or disable peer verification.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL
+amqp_ssl_socket_set_verify(amqp_socket_t *self,
+                           amqp_boolean_t verify);
+
+/**
+ * Sets whether rabbitmq-c initializes the underlying SSL library.
+ *
+ * For SSL libraries that require a one-time initialization across
+ * a whole program (e.g., OpenSSL) this sets whether or not rabbitmq-c
+ * will initialize the SSL library when the first call to
+ * amqp_open_socket() is made. You should call this function with
+ * do_init = 0 if the underlying SSL library is initialized somewhere else
+ * the program.
+ *
+ * Failing to initialize or double initialization of the SSL library will
+ * result in undefined behavior
+ *
+ * By default rabbitmq-c will initialize the underlying SSL library
+ *
+ * NOTE: calling this function after the first socket has been opened with
+ * amqp_open_socket() will not have any effect.
+ *
+ * \param [in] do_initialize If 0 rabbitmq-c will not initialize the SSL
+ *                           library, otherwise rabbitmq-c will initialize the
+ *                           SSL library
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL
+amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize);
+
+AMQP_END_DECLS
+
+#endif /* AMQP_SSL_H */
diff --git a/modules/kazoo/deps/amqp_table.c b/modules/kazoo/deps/amqp_table.c
new file mode 100644
index 0000000..6fa6fd3
--- /dev/null
+++ b/modules/kazoo/deps/amqp_table.c
@@ -0,0 +1,614 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2013
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define INITIAL_ARRAY_SIZE 16
+#define INITIAL_TABLE_SIZE 16
+
+static int amqp_decode_field_value(amqp_bytes_t encoded,
+                                   amqp_pool_t *pool,
+                                   amqp_field_value_t *entry,
+                                   size_t *offset);
+
+static int amqp_encode_field_value(amqp_bytes_t encoded,
+                                   amqp_field_value_t *entry,
+                                   size_t *offset);
+
+/*---------------------------------------------------------------------------*/
+
+static int amqp_decode_array(amqp_bytes_t encoded,
+                             amqp_pool_t *pool,
+                             amqp_array_t *output,
+                             size_t *offset)
+{
+  uint32_t arraysize;
+  int num_entries = 0;
+  int allocated_entries = INITIAL_ARRAY_SIZE;
+  amqp_field_value_t *entries;
+  size_t limit;
+  int res;
+
+  if (!amqp_decode_32(encoded, offset, &arraysize)) {
+    return AMQP_STATUS_BAD_AMQP_DATA;
+  }
+
+  entries = malloc(allocated_entries * sizeof(amqp_field_value_t));
+  if (entries == NULL) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+
+  limit = *offset + arraysize;
+  while (*offset < limit) {
+    if (num_entries >= allocated_entries) {
+      void *newentries;
+      allocated_entries = allocated_entries * 2;
+      newentries = realloc(entries, allocated_entries * sizeof(amqp_field_value_t));
+      res = AMQP_STATUS_NO_MEMORY;
+      if (newentries == NULL) {
+        goto out;
+      }
+
+      entries = newentries;
+    }
+
+    res = amqp_decode_field_value(encoded, pool, &entries[num_entries],
+                                  offset);
+    if (res < 0) {
+      goto out;
+    }
+
+    num_entries++;
+  }
+
+  output->num_entries = num_entries;
+  output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_field_value_t));
+  res = AMQP_STATUS_NO_MEMORY;
+  /* NULL is legitimate if we requested a zero-length block. */
+  if (output->entries == NULL && num_entries > 0) {
+    goto out;
+  }
+
+  memcpy(output->entries, entries, num_entries * sizeof(amqp_field_value_t));
+  res = 0;
+
+out:
+  free(entries);
+  return res;
+}
+
+int amqp_decode_table(amqp_bytes_t encoded,
+                      amqp_pool_t *pool,
+                      amqp_table_t *output,
+                      size_t *offset)
+{
+  uint32_t tablesize;
+  int num_entries = 0;
+  amqp_table_entry_t *entries;
+  int allocated_entries = INITIAL_TABLE_SIZE;
+  size_t limit;
+  int res;
+
+  if (!amqp_decode_32(encoded, offset, &tablesize)) {
+    return AMQP_STATUS_BAD_AMQP_DATA;
+  }
+
+  entries = malloc(allocated_entries * sizeof(amqp_table_entry_t));
+  if (entries == NULL) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+
+  limit = *offset + tablesize;
+  while (*offset < limit) {
+    uint8_t keylen;
+
+    res = AMQP_STATUS_BAD_AMQP_DATA;
+    if (!amqp_decode_8(encoded, offset, &keylen)) {
+      goto out;
+    }
+
+    if (num_entries >= allocated_entries) {
+      void *newentries;
+      allocated_entries = allocated_entries * 2;
+      newentries = realloc(entries, allocated_entries * sizeof(amqp_table_entry_t));
+      res = AMQP_STATUS_NO_MEMORY;
+      if (newentries == NULL) {
+        goto out;
+      }
+
+      entries = newentries;
+    }
+
+    res = AMQP_STATUS_BAD_AMQP_DATA;
+    if (!amqp_decode_bytes(encoded, offset, &entries[num_entries].key, keylen)) {
+      goto out;
+    }
+
+    res = amqp_decode_field_value(encoded, pool, &entries[num_entries].value,
+                                  offset);
+    if (res < 0) {
+      goto out;
+    }
+
+    num_entries++;
+  }
+
+  output->num_entries = num_entries;
+  output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_table_entry_t));
+  res = AMQP_STATUS_NO_MEMORY;
+  /* NULL is legitimate if we requested a zero-length block. */
+  if (output->entries == NULL && num_entries > 0) {
+    goto out;
+  }
+
+  memcpy(output->entries, entries, num_entries * sizeof(amqp_table_entry_t));
+  res = AMQP_STATUS_OK;
+
+out:
+  free(entries);
+  return res;
+}
+
+static int amqp_decode_field_value(amqp_bytes_t encoded,
+                                   amqp_pool_t *pool,
+                                   amqp_field_value_t *entry,
+                                   size_t *offset)
+{
+  int res = AMQP_STATUS_BAD_AMQP_DATA;
+
+  if (!amqp_decode_8(encoded, offset, &entry->kind)) {
+    goto out;
+  }
+
+#define TRIVIAL_FIELD_DECODER(bits) if (!amqp_decode_##bits(encoded, offset, &entry->value.u##bits)) goto out; break
+#define SIMPLE_FIELD_DECODER(bits, dest, how) { uint##bits##_t val; if (!amqp_decode_##bits(encoded, offset, &val)) goto out; entry->value.dest = how; } break
+
+  switch (entry->kind) {
+  case AMQP_FIELD_KIND_BOOLEAN:
+    SIMPLE_FIELD_DECODER(8, boolean, val ? 1 : 0);
+
+  case AMQP_FIELD_KIND_I8:
+    SIMPLE_FIELD_DECODER(8, i8, (int8_t)val);
+  case AMQP_FIELD_KIND_U8:
+    TRIVIAL_FIELD_DECODER(8);
+
+  case AMQP_FIELD_KIND_I16:
+    SIMPLE_FIELD_DECODER(16, i16, (int16_t)val);
+  case AMQP_FIELD_KIND_U16:
+    TRIVIAL_FIELD_DECODER(16);
+
+  case AMQP_FIELD_KIND_I32:
+    SIMPLE_FIELD_DECODER(32, i32, (int32_t)val);
+  case AMQP_FIELD_KIND_U32:
+    TRIVIAL_FIELD_DECODER(32);
+
+  case AMQP_FIELD_KIND_I64:
+    SIMPLE_FIELD_DECODER(64, i64, (int64_t)val);
+  case AMQP_FIELD_KIND_U64:
+    TRIVIAL_FIELD_DECODER(64);
+
+  case AMQP_FIELD_KIND_F32:
+    TRIVIAL_FIELD_DECODER(32);
+    /* and by punning, f32 magically gets the right value...! */
+
+  case AMQP_FIELD_KIND_F64:
+    TRIVIAL_FIELD_DECODER(64);
+    /* and by punning, f64 magically gets the right value...! */
+
+  case AMQP_FIELD_KIND_DECIMAL:
+    if (!amqp_decode_8(encoded, offset, &entry->value.decimal.decimals)
+        || !amqp_decode_32(encoded, offset, &entry->value.decimal.value)) {
+      goto out;
+    }
+    break;
+
+  case AMQP_FIELD_KIND_UTF8:
+    /* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the
+       same implementation, but different interpretations. */
+    /* fall through */
+  case AMQP_FIELD_KIND_BYTES: {
+    uint32_t len;
+    if (!amqp_decode_32(encoded, offset, &len)
+        || !amqp_decode_bytes(encoded, offset, &entry->value.bytes, len)) {
+      goto out;
+    }
+    break;
+  }
+
+  case AMQP_FIELD_KIND_ARRAY:
+    res = amqp_decode_array(encoded, pool, &(entry->value.array), offset);
+    goto out;
+
+  case AMQP_FIELD_KIND_TIMESTAMP:
+    TRIVIAL_FIELD_DECODER(64);
+
+  case AMQP_FIELD_KIND_TABLE:
+    res = amqp_decode_table(encoded, pool, &(entry->value.table), offset);
+    goto out;
+
+  case AMQP_FIELD_KIND_VOID:
+    break;
+
+  default:
+    goto out;
+  }
+
+  res = AMQP_STATUS_OK;
+
+out:
+  return res;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int amqp_encode_array(amqp_bytes_t encoded,
+                             amqp_array_t *input,
+                             size_t *offset)
+{
+  size_t start = *offset;
+  int i, res;
+
+  *offset += 4; /* size of the array gets filled in later on */
+
+  for (i = 0; i < input->num_entries; i++) {
+    res = amqp_encode_field_value(encoded, &input->entries[i], offset);
+    if (res < 0) {
+      goto out;
+    }
+  }
+
+  if (!amqp_encode_32(encoded, &start, *offset - start - 4)) {
+    res = AMQP_STATUS_TABLE_TOO_BIG;
+    goto out;
+  }
+
+  res = AMQP_STATUS_OK;
+
+out:
+  return res;
+}
+
+int amqp_encode_table(amqp_bytes_t encoded,
+                      amqp_table_t *input,
+                      size_t *offset)
+{
+  size_t start = *offset;
+  int i, res;
+
+  *offset += 4; /* size of the table gets filled in later on */
+
+  for (i = 0; i < input->num_entries; i++) {
+    if (!amqp_encode_8(encoded, offset, input->entries[i].key.len)) {
+      res = AMQP_STATUS_TABLE_TOO_BIG;
+      goto out;
+    }
+
+    if (!amqp_encode_bytes(encoded, offset, input->entries[i].key)) {
+      res = AMQP_STATUS_TABLE_TOO_BIG;
+      goto out;
+    }
+
+    res = amqp_encode_field_value(encoded, &input->entries[i].value, offset);
+    if (res < 0) {
+      goto out;
+    }
+  }
+
+  if (!amqp_encode_32(encoded, &start, *offset - start - 4)) {
+    res = AMQP_STATUS_TABLE_TOO_BIG;
+    goto out;
+  }
+
+  res = AMQP_STATUS_OK;
+
+out:
+  return res;
+}
+
+static int amqp_encode_field_value(amqp_bytes_t encoded,
+                                   amqp_field_value_t *entry,
+                                   size_t *offset)
+{
+  int res = AMQP_STATUS_BAD_AMQP_DATA;
+
+  if (!amqp_encode_8(encoded, offset, entry->kind)) {
+    goto out;
+  }
+
+#define FIELD_ENCODER(bits, val) if (!amqp_encode_##bits(encoded, offset, val)) { \
+                                    res = AMQP_STATUS_TABLE_TOO_BIG;              \
+                                    goto out;                                     \
+                                  }                                               \
+                                  break
+
+  switch (entry->kind) {
+  case AMQP_FIELD_KIND_BOOLEAN:
+    FIELD_ENCODER(8, entry->value.boolean ? 1 : 0);
+
+  case AMQP_FIELD_KIND_I8:
+    FIELD_ENCODER(8, entry->value.i8);
+  case AMQP_FIELD_KIND_U8:
+    FIELD_ENCODER(8, entry->value.u8);
+
+  case AMQP_FIELD_KIND_I16:
+    FIELD_ENCODER(16, entry->value.i16);
+  case AMQP_FIELD_KIND_U16:
+    FIELD_ENCODER(16, entry->value.u16);
+
+  case AMQP_FIELD_KIND_I32:
+    FIELD_ENCODER(32, entry->value.i32);
+  case AMQP_FIELD_KIND_U32:
+    FIELD_ENCODER(32, entry->value.u32);
+
+  case AMQP_FIELD_KIND_I64:
+    FIELD_ENCODER(64, entry->value.i64);
+  case AMQP_FIELD_KIND_U64:
+    FIELD_ENCODER(64, entry->value.u64);
+
+  case AMQP_FIELD_KIND_F32:
+    /* by punning, u32 magically gets the right value...! */
+    FIELD_ENCODER(32, entry->value.u32);
+
+  case AMQP_FIELD_KIND_F64:
+    /* by punning, u64 magically gets the right value...! */
+    FIELD_ENCODER(64, entry->value.u64);
+
+  case AMQP_FIELD_KIND_DECIMAL:
+    if (!amqp_encode_8(encoded, offset, entry->value.decimal.decimals)
+        || !amqp_encode_32(encoded, offset, entry->value.decimal.value)) {
+      res = AMQP_STATUS_TABLE_TOO_BIG;
+      goto out;
+    }
+    break;
+
+  case AMQP_FIELD_KIND_UTF8:
+    /* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the
+       same implementation, but different interpretations. */
+    /* fall through */
+  case AMQP_FIELD_KIND_BYTES:
+    if (!amqp_encode_32(encoded, offset, entry->value.bytes.len)
+        || !amqp_encode_bytes(encoded, offset, entry->value.bytes)) {
+      res = AMQP_STATUS_TABLE_TOO_BIG;
+      goto out;
+    }
+    break;
+
+  case AMQP_FIELD_KIND_ARRAY:
+    res = amqp_encode_array(encoded, &entry->value.array, offset);
+    goto out;
+
+  case AMQP_FIELD_KIND_TIMESTAMP:
+    FIELD_ENCODER(64, entry->value.u64);
+
+  case AMQP_FIELD_KIND_TABLE:
+    res = amqp_encode_table(encoded, &entry->value.table, offset);
+    goto out;
+
+  case AMQP_FIELD_KIND_VOID:
+    break;
+
+  default:
+    res = AMQP_STATUS_INVALID_PARAMETER;
+    goto out;
+  }
+
+  res = AMQP_STATUS_OK;
+
+out:
+  return res;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int amqp_table_entry_cmp(void const *entry1, void const *entry2)
+{
+  amqp_table_entry_t const *p1 = (amqp_table_entry_t const *) entry1;
+  amqp_table_entry_t const *p2 = (amqp_table_entry_t const *) entry2;
+
+  int d;
+  size_t minlen;
+
+  minlen = p1->key.len;
+  if (p2->key.len < minlen) {
+    minlen = p2->key.len;
+  }
+
+  d = memcmp(p1->key.bytes, p2->key.bytes, minlen);
+  if (d != 0) {
+    return d;
+  }
+
+  return p1->key.len - p2->key.len;
+}
+
+static int
+amqp_field_value_clone(amqp_field_value_t *original, amqp_field_value_t *clone, amqp_pool_t *pool)
+{
+  int i;
+  int res;
+  clone->kind = original->kind;
+
+  switch (clone->kind) {
+    case AMQP_FIELD_KIND_BOOLEAN:
+      clone->value.boolean = original->value.boolean;
+      break;
+
+    case AMQP_FIELD_KIND_I8:
+      clone->value.i8 = original->value.i8;
+      break;
+
+    case AMQP_FIELD_KIND_U8:
+      clone->value.u8 = original->value.u8;
+      break;
+
+    case AMQP_FIELD_KIND_I16:
+      clone->value.i16 = original->value.i16;
+      break;
+
+    case AMQP_FIELD_KIND_U16:
+      clone->value.u16 = original->value.u16;
+      break;
+
+    case AMQP_FIELD_KIND_I32:
+      clone->value.i32 = original->value.i32;
+      break;
+
+    case AMQP_FIELD_KIND_U32:
+      clone->value.u32 = original->value.u32;
+      break;
+
+    case AMQP_FIELD_KIND_I64:
+      clone->value.i64 = original->value.i64;
+      break;
+
+    case AMQP_FIELD_KIND_U64:
+    case AMQP_FIELD_KIND_TIMESTAMP:
+      clone->value.u64 = original->value.u64;
+      break;
+
+    case AMQP_FIELD_KIND_F32:
+      clone->value.f32 = original->value.f32;
+      break;
+
+    case AMQP_FIELD_KIND_F64:
+      clone->value.f64 = original->value.f64;
+      break;
+
+    case AMQP_FIELD_KIND_DECIMAL:
+      clone->value.decimal = original->value.decimal;
+      break;
+
+    case AMQP_FIELD_KIND_UTF8:
+    case AMQP_FIELD_KIND_BYTES:
+      if (0 == original->value.bytes.len) {
+        clone->value.bytes = amqp_empty_bytes;
+      } else {
+        amqp_pool_alloc_bytes(pool, original->value.bytes.len, &clone->value.bytes);
+        if (NULL == clone->value.bytes.bytes) {
+          return AMQP_STATUS_NO_MEMORY;
+        }
+        memcpy(clone->value.bytes.bytes, original->value.bytes.bytes, clone->value.bytes.len);
+      }
+      break;
+
+    case AMQP_FIELD_KIND_ARRAY:
+      if (0 == original->value.array.entries) {
+        clone->value.array = amqp_empty_array;
+      } else {
+        clone->value.array.num_entries = original->value.array.num_entries;
+        clone->value.array.entries = amqp_pool_alloc(pool, clone->value.array.num_entries * sizeof(amqp_field_value_t));
+        if (NULL == clone->value.array.entries) {
+          return AMQP_STATUS_NO_MEMORY;
+        }
+
+        for (i = 0; i < clone->value.array.num_entries; ++i) {
+          res = amqp_field_value_clone(&original->value.array.entries[i], &clone->value.array.entries[i], pool);
+          if (AMQP_STATUS_OK != res) {
+            return res;
+          }
+        }
+      }
+      break;
+
+    case AMQP_FIELD_KIND_TABLE:
+      return amqp_table_clone(&original->value.table, &clone->value.table, pool);
+
+    case AMQP_FIELD_KIND_VOID:
+      break;
+
+    default:
+      return AMQP_STATUS_INVALID_PARAMETER;
+  }
+
+  return AMQP_STATUS_OK;
+}
+
+
+static int
+amqp_table_entry_clone(amqp_table_entry_t *original, amqp_table_entry_t *clone, amqp_pool_t *pool)
+{
+  if (0 == original->key.len) {
+    return AMQP_STATUS_INVALID_PARAMETER;
+  }
+
+  amqp_pool_alloc_bytes(pool, original->key.len, &clone->key);
+  if (NULL == clone->key.bytes) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+
+  memcpy(clone->key.bytes, original->key.bytes, clone->key.len);
+
+  return amqp_field_value_clone(&original->value, &clone->value, pool);
+}
+
+int
+amqp_table_clone(amqp_table_t *original, amqp_table_t *clone, amqp_pool_t *pool)
+{
+  int i;
+  int res;
+  clone->num_entries = original->num_entries;
+  if (0 == clone->num_entries) {
+    *clone = amqp_empty_table;
+    return AMQP_STATUS_OK;
+  }
+
+  clone->entries = amqp_pool_alloc(pool, clone->num_entries * sizeof(amqp_table_entry_t));
+
+  if (NULL == clone->entries) {
+    return AMQP_STATUS_NO_MEMORY;
+  }
+
+  for (i = 0; i < clone->num_entries; ++i) {
+    res = amqp_table_entry_clone(&original->entries[i], &clone->entries[i], pool);
+    if (AMQP_STATUS_OK != res) {
+      goto error_out1;
+    }
+  }
+
+  return AMQP_STATUS_OK;
+
+error_out1:
+  return res;
+}
diff --git a/modules/kazoo/deps/amqp_tcp_socket.c b/modules/kazoo/deps/amqp_tcp_socket.c
new file mode 100644
index 0000000..ed38c06
--- /dev/null
+++ b/modules/kazoo/deps/amqp_tcp_socket.c
@@ -0,0 +1,303 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Copyright 2012-2013 Michael Steinert
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include "amqp_tcp_socket.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct amqp_tcp_socket_t {
+  const struct amqp_socket_class_t *klass;
+  int sockfd;
+  void *buffer;
+  size_t buffer_length;
+  int internal_error;
+};
+
+
+static ssize_t
+amqp_tcp_socket_send_inner(void *base, const void *buf, size_t len, int flags)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+  ssize_t res;
+
+  const char *buf_left = buf;
+  ssize_t len_left = len;
+
+#ifdef MSG_NOSIGNAL
+  flags |= MSG_NOSIGNAL;
+#endif
+
+start:
+  res = send(self->sockfd, buf_left, len_left, flags);
+
+  if (res < 0) {
+    self->internal_error = amqp_os_socket_error();
+    if (EINTR == self->internal_error) {
+      goto start;
+    } else {
+      res = AMQP_STATUS_SOCKET_ERROR;
+    }
+  } else {
+    if (res == len_left) {
+      self->internal_error = 0;
+      res = AMQP_STATUS_OK;
+    } else {
+      buf_left += res;
+      len_left -= res;
+      goto start;
+    }
+  }
+
+  return res;
+}
+
+static ssize_t
+amqp_tcp_socket_send(void *base, const void *buf, size_t len)
+{
+  return amqp_tcp_socket_send_inner(base, buf, len, 0);
+}
+
+static ssize_t
+amqp_tcp_socket_writev(void *base, struct iovec *iov, int iovcnt)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+  ssize_t ret;
+
+#if defined(_WIN32)
+  DWORD res;
+  /* Making the assumption here that WSAsend won't do a partial send
+   * unless an error occured, in which case we're hosed so it doesn't matter */
+  if (WSASend(self->sockfd, (LPWSABUF)iov, iovcnt, &res, 0, NULL, NULL) == 0) {
+    self->internal_error = 0;
+    ret = AMQP_STATUS_OK;
+  } else {
+    self->internal_error = WSAGetLastError();
+    ret = AMQP_STATUS_SOCKET_ERROR;
+  }
+  return ret;
+
+#elif defined(MSG_MORE)
+  int i;
+  for (i = 0; i < iovcnt - 1; ++i) {
+    ret = amqp_tcp_socket_send_inner(self, iov[i].iov_base, iov[i].iov_len, MSG_MORE);
+    if (ret != AMQP_STATUS_OK) {
+      goto exit;
+    }
+  }
+  ret = amqp_tcp_socket_send_inner(self, iov[i].iov_base, iov[i].iov_len, 0);
+
+exit:
+  return ret;
+
+#elif defined(SO_NOSIGPIPE) || !defined(MSG_NOSIGNAL)
+  int i;
+  ssize_t len_left = 0;
+
+
+  struct iovec *iov_left = iov;
+  int iovcnt_left = iovcnt;
+
+  for (i = 0; i < iovcnt; ++i) {
+    len_left += iov[i].iov_len;
+  }
+
+start:
+  ret = writev(self->sockfd, iov_left, iovcnt_left);
+
+  if (ret < 0) {
+    self->internal_error = amqp_os_socket_error();
+    if (EINTR == self->internal_error) {
+      goto start;
+    } else {
+      self->internal_error = amqp_os_socket_error();
+      ret = AMQP_STATUS_SOCKET_ERROR;
+    }
+  } else {
+    if (ret == len_left) {
+      self->internal_error = 0;
+      ret = AMQP_STATUS_OK;
+    } else {
+      len_left -= ret;
+      for (i = 0; i < iovcnt_left; ++i) {
+        if (ret < (ssize_t)iov_left[i].iov_len) {
+          iov_left[i].iov_base = ((char*)iov_left[i].iov_base) + ret;
+          iov_left[i].iov_len -= ret;
+
+          iovcnt_left -= i;
+          iov_left += i;
+          break;
+        } else {
+          ret -= iov_left[i].iov_len;
+        }
+      }
+      goto start;
+    }
+  }
+
+  return ret;
+
+#else
+  int i;
+  size_t bytes = 0;
+  void *bufferp;
+
+  for (i = 0; i < iovcnt; ++i) {
+    bytes += iov[i].iov_len;
+  }
+
+  if (self->buffer_length < bytes) {
+    self->buffer = realloc(self->buffer, bytes);
+    if (NULL == self->buffer) {
+      self->buffer_length = 0;
+      self->internal_error = 0;
+      ret = AMQP_STATUS_NO_MEMORY;
+      goto exit;
+    }
+    self->buffer_length = bytes;
+  }
+
+  bufferp = self->buffer;
+  for (i = 0; i < iovcnt; ++i) {
+    memcpy(bufferp, iov[i].iov_base, iov[i].iov_len);
+    bufferp += iov[i].iov_len;
+  }
+
+  ret = amqp_tcp_socket_send_inner(self, self->buffer, bytes, 0);
+
+exit:
+  return ret;
+#endif
+}
+
+static ssize_t
+amqp_tcp_socket_recv(void *base, void *buf, size_t len, int flags)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+  ssize_t ret;
+
+start:
+  ret = recv(self->sockfd, buf, len, flags);
+
+  if (0 > ret) {
+    self->internal_error = amqp_os_socket_error();
+    if (EINTR == self->internal_error) {
+      goto start;
+    } else {
+      ret = AMQP_STATUS_SOCKET_ERROR;
+    }
+  } else if (0 == ret) {
+    ret = AMQP_STATUS_CONNECTION_CLOSED;
+  }
+
+  return ret;
+}
+
+static int
+amqp_tcp_socket_open(void *base, const char *host, int port, struct timeval *timeout)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+  self->sockfd = amqp_open_socket_noblock(host, port, timeout);
+  if (0 > self->sockfd) {
+    int err = self->sockfd;
+    self->sockfd = -1;
+    return err;
+  }
+  return AMQP_STATUS_OK;
+}
+
+static int
+amqp_tcp_socket_close(void *base)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+
+  if (-1 != self->sockfd) {
+    if (amqp_os_socket_close(self->sockfd)) {
+      return AMQP_STATUS_SOCKET_ERROR;
+    }
+    self->sockfd = -1;
+  }
+
+  return AMQP_STATUS_OK;
+}
+
+static int
+amqp_tcp_socket_get_sockfd(void *base)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+  return self->sockfd;
+}
+
+static void
+amqp_tcp_socket_delete(void *base)
+{
+  struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base;
+
+  if (self) {
+    amqp_tcp_socket_close(self);
+    free(self->buffer);
+    free(self);
+  }
+}
+
+static const struct amqp_socket_class_t amqp_tcp_socket_class = {
+  amqp_tcp_socket_writev, /* writev */
+  amqp_tcp_socket_send, /* send */
+  amqp_tcp_socket_recv, /* recv */
+  amqp_tcp_socket_open, /* open */
+  amqp_tcp_socket_close, /* close */
+  amqp_tcp_socket_get_sockfd, /* get_sockfd */
+  amqp_tcp_socket_delete /* delete */
+};
+
+amqp_socket_t *
+amqp_tcp_socket_new(amqp_connection_state_t state)
+{
+  struct amqp_tcp_socket_t *self = calloc(1, sizeof(*self));
+  if (!self) {
+    return NULL;
+  }
+  self->klass = &amqp_tcp_socket_class;
+  self->sockfd = -1;
+
+  amqp_set_socket(state, (amqp_socket_t *)self);
+
+  return (amqp_socket_t *)self;
+}
+
+void
+amqp_tcp_socket_set_sockfd(amqp_socket_t *base, int sockfd)
+{
+  struct amqp_tcp_socket_t *self;
+  if (base->klass != &amqp_tcp_socket_class) {
+    amqp_abort("<%p> is not of type amqp_tcp_socket_t", base);
+  }
+  self = (struct amqp_tcp_socket_t *)base;
+  self->sockfd = sockfd;
+}
diff --git a/modules/kazoo/deps/amqp_tcp_socket.h b/modules/kazoo/deps/amqp_tcp_socket.h
new file mode 100644
index 0000000..7614aa5
--- /dev/null
+++ b/modules/kazoo/deps/amqp_tcp_socket.h
@@ -0,0 +1,73 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/** \file */
+/*
+ * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
+ * All Rights Reserved.
+ *
+ * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael
+ * Steinert. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * A TCP socket connection.
+ */
+
+#ifndef AMQP_TCP_SOCKET_H
+#define AMQP_TCP_SOCKET_H
+
+#include <amqp.h>
+
+AMQP_BEGIN_DECLS
+
+/**
+ * Create a new TCP socket.
+ *
+ * Call amqp_connection_close() to release socket resources.
+ *
+ * \return A new socket object or NULL if an error occurred.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+amqp_socket_t *
+AMQP_CALL
+amqp_tcp_socket_new(amqp_connection_state_t state);
+
+/**
+ * Assign an open file descriptor to a socket object.
+ *
+ * This function must not be used in conjunction with amqp_socket_open(), i.e.
+ * the socket connection should already be open(2) when this function is
+ * called.
+ *
+ * \param [in,out] self A TCP socket object.
+ * \param [in] sockfd An open socket descriptor.
+ *
+ * \since v0.4.0
+ */
+AMQP_PUBLIC_FUNCTION
+void
+AMQP_CALL
+amqp_tcp_socket_set_sockfd(amqp_socket_t *self, int sockfd);
+
+AMQP_END_DECLS
+
+#endif /* AMQP_TCP_SOCKET_H */
diff --git a/modules/kazoo/deps/amqp_timer.c b/modules/kazoo/deps/amqp_timer.c
new file mode 100644
index 0000000..46410dc
--- /dev/null
+++ b/modules/kazoo/deps/amqp_timer.c
@@ -0,0 +1,140 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "amqp.h"
+#include "amqp_timer.h"
+#include <string.h>
+
+#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
+# define AMQP_WIN_TIMER_API
+#elif (defined(machintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+# define AMQP_MAC_TIMER_API
+#else
+# define AMQP_POSIX_TIMER_API
+#endif
+
+
+#ifdef AMQP_WIN_TIMER_API
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+uint64_t
+amqp_get_monotonic_timestamp(void)
+{
+  static double NS_PER_COUNT = 0;
+  LARGE_INTEGER perf_count;
+
+  if (0 == NS_PER_COUNT) {
+    LARGE_INTEGER perf_frequency;
+    if (!QueryPerformanceFrequency(&perf_frequency)) {
+      return 0;
+    }
+    NS_PER_COUNT = (double)AMQP_NS_PER_S / perf_frequency.QuadPart;
+  }
+
+  if (!QueryPerformanceCounter(&perf_count)) {
+    return 0;
+  }
+
+  return (uint64_t)(perf_count.QuadPart * NS_PER_COUNT);
+}
+#endif /* AMQP_WIN_TIMER_API */
+
+#ifdef AMQP_MAC_TIMER_API
+# include <mach/mach_time.h>
+
+uint64_t
+amqp_get_monotonic_timestamp(void)
+{
+  static mach_timebase_info_data_t s_timebase = {0, 0};
+  uint64_t timestamp;
+
+  timestamp = mach_absolute_time();
+
+  if (s_timebase.denom == 0) {
+    mach_timebase_info(&s_timebase);
+    if (0 == s_timebase.denom) {
+      return 0;
+    }
+  }
+
+  timestamp *= (uint64_t)s_timebase.numer;
+  timestamp /= (uint64_t)s_timebase.denom;
+
+  return timestamp;
+}
+#endif /* AMQP_MAC_TIMER_API */
+
+#ifdef AMQP_POSIX_TIMER_API
+#include <time.h>
+
+uint64_t
+amqp_get_monotonic_timestamp(void)
+{
+#ifdef __hpux
+  return (uint64_t)gethrtime();
+#else
+  struct timespec tp;
+  if (-1 == clock_gettime(CLOCK_MONOTONIC, &tp)) {
+    return 0;
+  }
+
+  return ((uint64_t)tp.tv_sec * AMQP_NS_PER_S + (uint64_t)tp.tv_nsec);
+#endif
+}
+#endif /* AMQP_POSIX_TIMER_API */
+
+int
+amqp_timer_update(amqp_timer_t *timer, struct timeval *timeout)
+{
+  if (0 == timer->current_timestamp) {
+    timer->current_timestamp = amqp_get_monotonic_timestamp();
+
+    if (0 == timer->current_timestamp) {
+      return AMQP_STATUS_TIMER_FAILURE;
+    }
+
+    timer->timeout_timestamp = timer->current_timestamp +
+                               (uint64_t)timeout->tv_sec * AMQP_NS_PER_S +
+                               (uint64_t)timeout->tv_usec * AMQP_NS_PER_US;
+
+  } else {
+    timer->current_timestamp = amqp_get_monotonic_timestamp();
+
+    if (0 == timer->current_timestamp) {
+      return AMQP_STATUS_TIMER_FAILURE;
+    }
+  }
+
+  if (timer->current_timestamp > timer->timeout_timestamp) {
+    return AMQP_STATUS_TIMEOUT;
+  }
+
+  timer->ns_until_next_timeout = timer->timeout_timestamp - timer->current_timestamp;
+
+  memset(&timer->tv, 0, sizeof(struct timeval));
+  timer->tv.tv_sec = timer->ns_until_next_timeout / AMQP_NS_PER_S;
+  timer->tv.tv_usec = (timer->ns_until_next_timeout % AMQP_NS_PER_S) / AMQP_NS_PER_US;
+
+  return AMQP_STATUS_OK;
+}
diff --git a/modules/kazoo/deps/amqp_timer.h b/modules/kazoo/deps/amqp_timer.h
new file mode 100644
index 0000000..3936922
--- /dev/null
+++ b/modules/kazoo/deps/amqp_timer.h
@@ -0,0 +1,67 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef AMQP_TIMER_H
+#define AMQP_TIMER_H
+
+#include <stdint.h>
+
+#ifdef _WIN32
+# ifndef WINVER
+#  define WINVER 0x0502
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+# endif
+# include <Winsock2.h>
+#else
+# include <sys/time.h>
+#endif
+
+#define AMQP_MS_PER_S  1000
+#define AMQP_US_PER_MS 1000
+#define AMQP_NS_PER_S  1000000000
+#define AMQP_NS_PER_MS 1000000
+#define AMQP_NS_PER_US 1000
+
+#define AMQP_INIT_TIMER(structure) { \
+  structure.current_timestamp = 0;   \
+  structure.timeout_timestamp = 0;   \
+}
+
+typedef struct amqp_timer_t_ {
+  uint64_t current_timestamp;
+  uint64_t timeout_timestamp;
+  uint64_t ns_until_next_timeout;
+  struct timeval tv;
+} amqp_timer_t;
+
+/* Gets a monotonic timestamp in ns */
+uint64_t
+amqp_get_monotonic_timestamp(void);
+
+/* Prepare timeout value and modify timer state based on timer state. */
+int
+amqp_timer_update(amqp_timer_t *timer, struct timeval *timeout);
+
+#endif /* AMQP_TIMER_H */
diff --git a/modules/kazoo/deps/amqp_url.c b/modules/kazoo/deps/amqp_url.c
new file mode 100644
index 0000000..602b554
--- /dev/null
+++ b/modules/kazoo/deps/amqp_url.c
@@ -0,0 +1,218 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT
+ *
+ * Portions created by Alan Antonuk are Copyright (c) 2012-2013
+ * Alan Antonuk. All Rights Reserved.
+ *
+ * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010
+ * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "amqp_private.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void amqp_default_connection_info(struct amqp_connection_info *ci)
+{
+  /* Apply defaults */
+  ci->user = "guest";
+  ci->password = "guest";
+  ci->host = "localhost";
+  ci->port = 5672;
+  ci->vhost = "/";
+  ci->ssl = 0;
+}
+
+/* Scan for the next delimiter, handling percent-encodings on the way. */
+static char find_delim(char **pp, int colon_and_at_sign_are_delims)
+{
+  char *from = *pp;
+  char *to = from;
+
+  for (;;) {
+    char ch = *from++;
+
+    switch (ch) {
+    case ':':
+    case '@':
+      if (!colon_and_at_sign_are_delims) {
+        *to++ = ch;
+        break;
+      }
+
+      /* fall through */
+    case 0:
+    case '/':
+    case '?':
+    case '#':
+    case '[':
+    case ']':
+      *to = 0;
+      *pp = from;
+      return ch;
+
+    case '%': {
+      unsigned int val;
+      int chars;
+      int res = sscanf(from, "%2x%n", &val, &chars);
+
+      if (res == EOF || res < 1 || chars != 2)
+        /* Return a surprising delimiter to
+           force an error. */
+      {
+        return '%';
+      }
+
+      *to++ = val;
+      from += 2;
+      break;
+    }
+
+    default:
+      *to++ = ch;
+      break;
+    }
+  }
+}
+
+/* Parse an AMQP URL into its component parts. */
+int amqp_parse_url(char *url, struct amqp_connection_info *parsed)
+{
+  int res = AMQP_STATUS_BAD_URL;
+  char delim;
+  char *start;
+  char *host;
+  char *port = NULL;
+
+  /* check the prefix */
+  if (!strncmp(url, "amqp://", 7)) {
+    /* do nothing */
+  } else if (!strncmp(url, "amqps://", 8)) {
+    parsed->port = 5671;
+    parsed->ssl = 1;
+  } else {
+    goto out;
+  }
+
+  host = start = url += (parsed->ssl ? 8 : 7);
+  delim = find_delim(&url, 1);
+
+  if (delim == ':') {
+    /* The colon could be introducing the port or the
+       password part of the userinfo.  We don't know yet,
+       so stash the preceding component. */
+    port = start = url;
+    delim = find_delim(&url, 1);
+  }
+
+  if (delim == '@') {
+    /* What might have been the host and port were in fact
+       the username and password */
+    parsed->user = host;
+    if (port) {
+      parsed->password = port;
+    }
+
+    port = NULL;
+    host = start = url;
+    delim = find_delim(&url, 1);
+  }
+
+  if (delim == '[') {
+    /* IPv6 address.  The bracket should be the first
+       character in the host. */
+    if (host != start || *host != 0) {
+      goto out;
+    }
+
+    start = url;
+    delim = find_delim(&url, 0);
+
+    if (delim != ']') {
+      goto out;
+    }
+
+    parsed->host = start;
+    start = url;
+    delim = find_delim(&url, 1);
+
+    /* Closing bracket should be the last character in the
+       host. */
+    if (*start != 0) {
+      goto out;
+    }
+  } else {
+    /* If we haven't seen the host yet, this is it. */
+    if (*host != 0) {
+      parsed->host = host;
+    }
+  }
+
+  if (delim == ':') {
+    port = start = url;
+    delim = find_delim(&url, 1);
+  }
+
+  if (port) {
+    char *end;
+    long portnum = strtol(port, &end, 10);
+
+    if (port == end || *end != 0 || portnum < 0 || portnum > 65535) {
+      goto out;
+    }
+
+    parsed->port = portnum;
+  }
+
+  if (delim == '/') {
+    start = url;
+    delim = find_delim(&url, 1);
+
+    if (delim != 0) {
+      goto out;
+    }
+
+    parsed->vhost = start;
+    res = AMQP_STATUS_OK;
+  } else if (delim == 0) {
+    res = AMQP_STATUS_OK;
+  }
+
+  /* Any other delimiter is bad, and we will return
+     AMQP_STATUS_BAD_AMQP_URL. */
+
+out:
+  return res;
+}
diff --git a/modules/kazoo/deps/arraylist.c b/modules/kazoo/deps/arraylist.c
new file mode 100644
index 0000000..81b6fa2
--- /dev/null
+++ b/modules/kazoo/deps/arraylist.c
@@ -0,0 +1,101 @@
+/*
+ * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#endif /* STDC_HEADERS */
+
+#if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD)
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "bits.h"
+#include "arraylist.h"
+
+struct array_list*
+array_list_new(array_list_free_fn *free_fn)
+{
+  struct array_list *arr;
+
+  arr = (struct array_list*)calloc(1, sizeof(struct array_list));
+  if(!arr) return NULL;
+  arr->size = ARRAY_LIST_DEFAULT_SIZE;
+  arr->length = 0;
+  arr->free_fn = free_fn;
+  if(!(arr->array = (void**)calloc(sizeof(void*), arr->size))) {
+    free(arr);
+    return NULL;
+  }
+  return arr;
+}
+
+extern void
+array_list_free(struct array_list *arr)
+{
+  int i;
+  for(i = 0; i < arr->length; i++)
+    if(arr->array[i]) arr->free_fn(arr->array[i]);
+  free(arr->array);
+  free(arr);
+}
+
+void*
+array_list_get_idx(struct array_list *arr, int i)
+{
+  if(i >= arr->length) return NULL;
+  return arr->array[i];
+}
+
+static int array_list_expand_internal(struct array_list *arr, int max)
+{
+  void *t;
+  int new_size;
+
+  if(max < arr->size) return 0;
+  new_size = json_max(arr->size << 1, max);
+  if(!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
+  arr->array = (void**)t;
+  (void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*));
+  arr->size = new_size;
+  return 0;
+}
+
+int
+array_list_put_idx(struct array_list *arr, int idx, void *data)
+{
+  if(array_list_expand_internal(arr, idx+1)) return -1;
+  if(arr->array[idx]) arr->free_fn(arr->array[idx]);
+  arr->array[idx] = data;
+  if(arr->length <= idx) arr->length = idx + 1;
+  return 0;
+}
+
+int
+array_list_add(struct array_list *arr, void *data)
+{
+  return array_list_put_idx(arr, arr->length, data);
+}
+
+void
+array_list_sort(struct array_list *arr, int(*sort_fn)(const void *, const void *))
+{
+  qsort(arr->array, arr->length, sizeof(arr->array[0]),
+	(int (*)(const void *, const void *))sort_fn);
+}
+
+int
+array_list_length(struct array_list *arr)
+{
+  return arr->length;
+}
diff --git a/modules/kazoo/deps/arraylist.h b/modules/kazoo/deps/arraylist.h
new file mode 100644
index 0000000..4f3113c
--- /dev/null
+++ b/modules/kazoo/deps/arraylist.h
@@ -0,0 +1,56 @@
+/*
+ * $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _arraylist_h_
+#define _arraylist_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ARRAY_LIST_DEFAULT_SIZE 32
+
+typedef void (array_list_free_fn) (void *data);
+
+struct array_list
+{
+  void **array;
+  int length;
+  int size;
+  array_list_free_fn *free_fn;
+};
+
+extern struct array_list*
+array_list_new(array_list_free_fn *free_fn);
+
+extern void
+array_list_free(struct array_list *al);
+
+extern void*
+array_list_get_idx(struct array_list *al, int i);
+
+extern int
+array_list_put_idx(struct array_list *al, int i, void *data);
+
+extern int
+array_list_add(struct array_list *al, void *data);
+
+extern int
+array_list_length(struct array_list *al);
+
+extern void
+array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/bits.h b/modules/kazoo/deps/bits.h
new file mode 100644
index 0000000..c8cbbc8
--- /dev/null
+++ b/modules/kazoo/deps/bits.h
@@ -0,0 +1,28 @@
+/*
+ * $Id: bits.h,v 1.10 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _bits_h_
+#define _bits_h_
+
+#ifndef json_min
+#define json_min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef json_max
+#define json_max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
+#define error_ptr(error) ((void*)error)
+#define error_description(error)  (json_tokener_errors[error])
+#define is_error(ptr) (ptr == NULL)
+
+#endif
diff --git a/modules/kazoo/deps/config.h b/modules/kazoo/deps/config.h
new file mode 100644
index 0000000..6b7e9d5
--- /dev/null
+++ b/modules/kazoo/deps/config.h
@@ -0,0 +1,209 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Enable RDRANR Hardware RNG Hash Seed */
+/* #undef ENABLE_RDRAND */
+
+/* Define if .gnu.warning accepts long strings. */
+/* #undef HAS_GNU_WARNING_LONG */
+
+#define WITH_SSL 1
+
+/* Host operating system string */
+#define AMQ_PLATFORM "linux-gnu"
+
+/* Define to 1 to enable thread safety */
+#define ENABLE_THREAD_SAFETY 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if the function (or macro) htonll exists. */
+/* #undef HAVE_HTONLL */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if PolarSSL is available. */
+/* #undef HAVE_POLARSSL */
+
+/* Define to 1 if you have the <polarssl/ssl.h> header file. */
+/* #undef HAVE_POLARSSL_SSL_H */
+
+/* Define to 1 if Popt is available. */
+//#define HAVE_POPT 1
+
+/* Define to 1 if you have the <popt.h> header file. */
+//#define HAVE_POPT_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+
+/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
+   don't. */
+#define HAVE_DECL_INFINITY 1
+
+/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
+   */
+#define HAVE_DECL_ISINF 1
+
+/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
+   */
+#define HAVE_DECL_ISNAN 1
+
+/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
+#define HAVE_DECL_NAN 1
+
+/* Define to 1 if you have the declaration of `_finite', and to 0 if you
+   don't. */
+#define HAVE_DECL__FINITE 0
+
+/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't.
+   */
+#define HAVE_DECL__ISNAN 0
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <endian.h> header file. */
+#define HAVE_ENDIAN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `open' function. */
+#define HAVE_OPEN 1
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+   and to 0 otherwise. */
+#define HAVE_REALLOC 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/cdefs.h> header file. */
+#define HAVE_SYS_CDEFS_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `vasprintf' function. */
+//#define HAVE_VASPRINTF 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `vsyslog' function. */
+#define HAVE_VSYSLOG 1
+
+/* Public define for json_inttypes.h */
+#define JSON_C_HAVE_INTTYPES_H 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+
+
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
+
+/* Define to rpl_realloc if the replacement function should be used. */
+/* #undef realloc */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/modules/kazoo/deps/debug.c b/modules/kazoo/deps/debug.c
new file mode 100644
index 0000000..3b64b59
--- /dev/null
+++ b/modules/kazoo/deps/debug.c
@@ -0,0 +1,83 @@
+/*
+ * $Id: debug.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#if HAVE_SYSLOG_H
+# include <syslog.h>
+#endif /* HAVE_SYSLOG_H */
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#include "debug.h"
+
+static int _syslog = 0;
+static int _debug = 0;
+
+void mc_set_debug(int debug) { _debug = debug; }
+int mc_get_debug(void) { return _debug; }
+
+extern void mc_set_syslog(int syslog)
+{
+  _syslog = syslog;
+}
+
+void mc_debug(const char *msg, ...)
+{
+  va_list ap;
+  if(_debug) {
+    va_start(ap, msg);
+#if HAVE_VSYSLOG
+    if(_syslog) {
+		vsyslog(LOG_DEBUG, msg, ap);
+	} else
+#endif
+		vprintf(msg, ap);
+    va_end(ap);
+  }
+}
+
+void mc_error(const char *msg, ...)
+{
+  va_list ap;
+  va_start(ap, msg);
+#if HAVE_VSYSLOG
+    if(_syslog) {
+		vsyslog(LOG_ERR, msg, ap);
+	} else
+#endif
+		vfprintf(stderr, msg, ap);
+  va_end(ap);
+}
+
+void mc_info(const char *msg, ...)
+{
+  va_list ap;
+  va_start(ap, msg);
+#if HAVE_VSYSLOG
+    if(_syslog) {
+		vsyslog(LOG_INFO, msg, ap);
+	} else 
+#endif
+		vfprintf(stderr, msg, ap);
+  va_end(ap);
+}
diff --git a/modules/kazoo/deps/debug.h b/modules/kazoo/deps/debug.h
new file mode 100644
index 0000000..80ca3e4
--- /dev/null
+++ b/modules/kazoo/deps/debug.h
@@ -0,0 +1,71 @@
+/*
+ * $Id: debug.h,v 1.5 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void mc_set_debug(int debug);
+extern int mc_get_debug(void);
+
+extern void mc_set_syslog(int syslog);
+
+extern void mc_debug(const char *msg, ...);
+extern void mc_error(const char *msg, ...);
+extern void mc_info(const char *msg, ...);
+
+#ifndef __STRING
+#define __STRING(x) #x
+#endif
+
+#ifndef PARSER_BROKEN_FIXED
+
+#define JASSERT(cond) do {} while(0)
+
+#else
+
+#define JASSERT(cond) do { \
+		if (!(cond)) { \
+			mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \
+			*(int *)0 = 1;\
+			abort(); \
+		}\
+	} while(0)
+
+#endif
+
+#define MC_ERROR(x, ...) mc_error(x, ##__VA_ARGS__)
+
+#ifdef MC_MAINTAINER_MODE
+#define MC_SET_DEBUG(x) mc_set_debug(x)
+#define MC_GET_DEBUG() mc_get_debug()
+#define MC_SET_SYSLOG(x) mc_set_syslog(x)
+#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
+#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
+#else
+#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
+#define MC_GET_DEBUG() (0)
+#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
+#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
+#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/json.h b/modules/kazoo/deps/json.h
new file mode 100644
index 0000000..4339b20
--- /dev/null
+++ b/modules/kazoo/deps/json.h
@@ -0,0 +1,34 @@
+/*
+ * $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_h_
+#define _json_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bits.h"
+#include "debug.h"
+#include "linkhash.h"
+#include "arraylist.h"
+#include "json_util.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_object_iterator.h"
+#include "json_c_version.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/json_c_version.c b/modules/kazoo/deps/json_c_version.c
new file mode 100644
index 0000000..13eb188
--- /dev/null
+++ b/modules/kazoo/deps/json_c_version.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Eric Haszlakiewicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+#include "config.h"
+
+#include "json_c_version.h"
+
+const char *json_c_version(void)
+{
+	return JSON_C_VERSION;
+}
+
+int json_c_version_num(void)
+{
+	return JSON_C_VERSION_NUM;
+}
+
diff --git a/modules/kazoo/deps/json_c_version.h b/modules/kazoo/deps/json_c_version.h
new file mode 100644
index 0000000..eed98a4
--- /dev/null
+++ b/modules/kazoo/deps/json_c_version.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Eric Haszlakiewicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+
+#ifndef _json_c_version_h_
+#define _json_c_version_h_
+
+#define JSON_C_MAJOR_VERSION 0
+#define JSON_C_MINOR_VERSION 12
+#define JSON_C_MICRO_VERSION 0
+#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
+                            (JSON_C_MINOR_VERSION << 8) | \
+                            JSON_C_MICRO_VERSION)
+#define JSON_C_VERSION "0.12"
+
+const char *json_c_version(void); /* Returns JSON_C_VERSION */
+int json_c_version_num(void);     /* Returns JSON_C_VERSION_NUM */
+
+#endif
diff --git a/modules/kazoo/deps/json_config.h b/modules/kazoo/deps/json_config.h
new file mode 100644
index 0000000..965ff1c
--- /dev/null
+++ b/modules/kazoo/deps/json_config.h
@@ -0,0 +1,4 @@
+/* json_config.h.  Generated from json_config.h.in by configure.  */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define JSON_C_HAVE_INTTYPES_H 1
diff --git a/modules/kazoo/deps/json_inttypes.h b/modules/kazoo/deps/json_inttypes.h
new file mode 100644
index 0000000..9de8d24
--- /dev/null
+++ b/modules/kazoo/deps/json_inttypes.h
@@ -0,0 +1,28 @@
+
+#ifndef _json_inttypes_h_
+#define _json_inttypes_h_
+
+#include "json_config.h"
+
+#if defined(_MSC_VER) && _MSC_VER <= 1700
+
+/* Anything less than Visual Studio C++ 10 is missing stdint.h and inttypes.h */
+typedef __int32 int32_t;
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    ((int32_t)_I32_MAX)
+typedef __int64 int64_t;
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    ((int64_t)_I64_MAX)
+#define PRId64 "I64d"
+#define SCNd64 "I64d"
+
+#else
+
+#ifdef JSON_C_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+/* inttypes.h includes stdint.h */
+
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/json_object.c b/modules/kazoo/deps/json_object.c
new file mode 100644
index 0000000..6cc73bc
--- /dev/null
+++ b/modules/kazoo/deps/json_object.c
@@ -0,0 +1,855 @@
+/*
+ * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "printbuf.h"
+#include "linkhash.h"
+#include "arraylist.h"
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_object_private.h"
+#include "json_util.h"
+#include "math_compat.h"
+
+#if !defined(HAVE_STRDUP) && defined(_MSC_VER)
+  /* MSC has the version as _strdup */
+# define strdup _strdup
+#elif !defined(HAVE_STRDUP)
+# error You do not have strdup on your system.
+#endif /* HAVE_STRDUP */
+
+#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
+  /* MSC has the version as _snprintf */
+# define snprintf _snprintf
+#elif !defined(HAVE_SNPRINTF)
+# error You do not have snprintf on your system.
+#endif /* HAVE_SNPRINTF */
+
+// Don't define this.  It's not thread-safe.
+/* #define REFCOUNT_DEBUG 1 */
+
+const char *json_number_chars = "0123456789.+-eE";
+const char *json_hex_chars = "0123456789abcdefABCDEF";
+
+static void json_object_generic_delete(struct json_object* jso);
+static struct json_object* json_object_new(enum json_type o_type);
+
+static json_object_to_json_string_fn json_object_object_to_json_string;
+static json_object_to_json_string_fn json_object_boolean_to_json_string;
+static json_object_to_json_string_fn json_object_int_to_json_string;
+static json_object_to_json_string_fn json_object_double_to_json_string;
+static json_object_to_json_string_fn json_object_string_to_json_string;
+static json_object_to_json_string_fn json_object_array_to_json_string;
+
+
+/* ref count debugging */
+
+#ifdef REFCOUNT_DEBUG
+
+static struct lh_table *json_object_table;
+
+static void json_object_init(void) __attribute__ ((constructor));
+static void json_object_init(void) {
+  MC_DEBUG("json_object_init: creating object table\n");
+  json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
+}
+
+static void json_object_fini(void) __attribute__ ((destructor));
+static void json_object_fini(void) {
+  struct lh_entry *ent;
+  if(MC_GET_DEBUG()) {
+    if (json_object_table->count) {
+      MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
+  	       json_object_table->count);
+      lh_foreach(json_object_table, ent) {
+        struct json_object* obj = (struct json_object*)ent->v;
+        MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
+      }
+    }
+  }
+  MC_DEBUG("json_object_fini: freeing object table\n");
+  lh_table_free(json_object_table);
+}
+#endif /* REFCOUNT_DEBUG */
+
+
+/* string escaping */
+
+static int json_escape_str(struct printbuf *pb, char *str, int len)
+{
+  int pos = 0, start_offset = 0;
+  unsigned char c;
+  while (len--) {
+    c = str[pos];
+    switch(c) {
+    case '\b':
+    case '\n':
+    case '\r':
+    case '\t':
+    case '\f':
+    case '"':
+    case '\\':
+    case '/':
+      if(pos - start_offset > 0)
+	printbuf_memappend(pb, str + start_offset, pos - start_offset);
+      if(c == '\b') printbuf_memappend(pb, "\\b", 2);
+      else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
+      else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
+      else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
+      else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
+      else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
+      else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
+      else if(c == '/') printbuf_memappend(pb, "\\/", 2);
+      start_offset = ++pos;
+      break;
+    default:
+      if(c < ' ') {
+	if(pos - start_offset > 0)
+	  printbuf_memappend(pb, str + start_offset, pos - start_offset);
+	sprintbuf(pb, "\\u00%c%c",
+		  json_hex_chars[c >> 4],
+		  json_hex_chars[c & 0xf]);
+	start_offset = ++pos;
+      } else pos++;
+    }
+  }
+  if(pos - start_offset > 0)
+    printbuf_memappend(pb, str + start_offset, pos - start_offset);
+  return 0;
+}
+
+
+/* reference counting */
+
+extern struct json_object* json_object_get(struct json_object *jso)
+{
+  if(jso) {
+    jso->_ref_count++;
+  }
+  return jso;
+}
+
+int json_object_put(struct json_object *jso)
+{
+	if(jso)
+	{
+		jso->_ref_count--;
+		if(!jso->_ref_count)
+		{
+			if (jso->_user_delete)
+				jso->_user_delete(jso, jso->_userdata);
+			jso->_delete(jso);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+/* generic object construction and destruction parts */
+
+static void json_object_generic_delete(struct json_object* jso)
+{
+#ifdef REFCOUNT_DEBUG
+  MC_DEBUG("json_object_delete_%s: %p\n",
+	   json_type_to_name(jso->o_type), jso);
+  lh_table_delete(json_object_table, jso);
+#endif /* REFCOUNT_DEBUG */
+  printbuf_free(jso->_pb);
+  free(jso);
+}
+
+static struct json_object* json_object_new(enum json_type o_type)
+{
+  struct json_object *jso;
+
+  jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
+  if(!jso) return NULL;
+  jso->o_type = o_type;
+  jso->_ref_count = 1;
+  jso->_delete = &json_object_generic_delete;
+#ifdef REFCOUNT_DEBUG
+  lh_table_insert(json_object_table, jso, jso);
+  MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
+#endif /* REFCOUNT_DEBUG */
+  return jso;
+}
+
+
+/* type checking functions */
+
+int json_object_is_type(struct json_object *jso, enum json_type type)
+{
+  if (!jso)
+    return (type == json_type_null);
+  return (jso->o_type == type);
+}
+
+enum json_type json_object_get_type(struct json_object *jso)
+{
+  if (!jso)
+    return json_type_null;
+  return jso->o_type;
+}
+
+/* set a custom conversion to string */
+
+void json_object_set_serializer(json_object *jso,
+	json_object_to_json_string_fn to_string_func,
+	void *userdata,
+	json_object_delete_fn *user_delete)
+{
+	// First, clean up any previously existing user info
+	if (jso->_user_delete)
+	{
+		jso->_user_delete(jso, jso->_userdata);
+	}
+	jso->_userdata = NULL;
+	jso->_user_delete = NULL;
+
+	if (to_string_func == NULL)
+	{
+		// Reset to the standard serialization function
+		switch(jso->o_type)
+		{
+		case json_type_null:
+			jso->_to_json_string = NULL;
+			break;
+		case json_type_boolean:
+			jso->_to_json_string = &json_object_boolean_to_json_string;
+			break;
+		case json_type_double:
+			jso->_to_json_string = &json_object_double_to_json_string;
+			break;
+		case json_type_int:
+			jso->_to_json_string = &json_object_int_to_json_string;
+			break;
+		case json_type_object:
+			jso->_to_json_string = &json_object_object_to_json_string;
+			break;
+		case json_type_array:
+			jso->_to_json_string = &json_object_array_to_json_string;
+			break;
+		case json_type_string:
+			jso->_to_json_string = &json_object_string_to_json_string;
+			break;
+		}
+		return;
+	}
+
+	jso->_to_json_string = to_string_func;
+	jso->_userdata = userdata;
+	jso->_user_delete = user_delete;
+}
+
+
+/* extended conversion to string */
+
+const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
+{
+	if (!jso)
+		return "null";
+
+	if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
+		return NULL;
+
+	printbuf_reset(jso->_pb);
+
+	if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
+		return NULL;
+
+	return jso->_pb->buf;
+}
+
+/* backwards-compatible conversion to string */
+
+const char* json_object_to_json_string(struct json_object *jso)
+{
+	return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
+}
+
+static void indent(struct printbuf *pb, int level, int flags)
+{
+	if (flags & JSON_C_TO_STRING_PRETTY)
+	{
+		printbuf_memset(pb, -1, ' ', level * 2);
+	}
+}
+
+/* json_object_object */
+
+static int json_object_object_to_json_string(struct json_object* jso,
+					     struct printbuf *pb,
+					     int level,
+						 int flags)
+{
+	int had_children = 0;
+	struct json_object_iter iter;
+
+	sprintbuf(pb, "{" /*}*/);
+	if (flags & JSON_C_TO_STRING_PRETTY)
+		sprintbuf(pb, "\n");
+	json_object_object_foreachC(jso, iter)
+	{
+		if (had_children)
+		{
+			sprintbuf(pb, ",");
+			if (flags & JSON_C_TO_STRING_PRETTY)
+				sprintbuf(pb, "\n");
+		}
+		had_children = 1;
+		if (flags & JSON_C_TO_STRING_SPACED)
+			sprintbuf(pb, " ");
+		indent(pb, level+1, flags);
+		sprintbuf(pb, "\"");
+		json_escape_str(pb, iter.key, strlen(iter.key));
+		if (flags & JSON_C_TO_STRING_SPACED)
+			sprintbuf(pb, "\": ");
+		else
+			sprintbuf(pb, "\":");
+		if(iter.val == NULL)
+			sprintbuf(pb, "null");
+		else
+			iter.val->_to_json_string(iter.val, pb, level+1,flags);
+	}
+	if (flags & JSON_C_TO_STRING_PRETTY)
+	{
+		if (had_children)
+			sprintbuf(pb, "\n");
+		indent(pb,level,flags);
+	}
+	if (flags & JSON_C_TO_STRING_SPACED)
+		return sprintbuf(pb, /*{*/ " }");
+	else
+		return sprintbuf(pb, /*{*/ "}");
+}
+
+
+static void json_object_lh_entry_free(struct lh_entry *ent)
+{
+  free(ent->k);
+  json_object_put((struct json_object*)ent->v);
+}
+
+static void json_object_object_delete(struct json_object* jso)
+{
+  lh_table_free(jso->o.c_object);
+  json_object_generic_delete(jso);
+}
+
+struct json_object* json_object_new_object(void)
+{
+  struct json_object *jso = json_object_new(json_type_object);
+  if(!jso) return NULL;
+  jso->_delete = &json_object_object_delete;
+  jso->_to_json_string = &json_object_object_to_json_string;
+  jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
+					NULL, &json_object_lh_entry_free);
+  return jso;
+}
+
+struct lh_table* json_object_get_object(struct json_object *jso)
+{
+  if(!jso) return NULL;
+  switch(jso->o_type) {
+  case json_type_object:
+    return jso->o.c_object;
+  default:
+    return NULL;
+  }
+}
+
+void json_object_object_add(struct json_object* jso, const char *key,
+			    struct json_object *val)
+{
+	// We lookup the entry and replace the value, rather than just deleting
+	// and re-adding it, so the existing key remains valid.
+	json_object *existing_value = NULL;
+	struct lh_entry *existing_entry;
+	existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
+	if (!existing_entry)
+	{
+		lh_table_insert(jso->o.c_object, strdup(key), val);
+		return;
+	}
+	existing_value = (void *)existing_entry->v;
+	if (existing_value)
+		json_object_put(existing_value);
+	existing_entry->v = val;
+}
+
+int json_object_object_length(struct json_object *jso)
+{
+	return lh_table_length(jso->o.c_object);
+}
+
+struct json_object* json_object_object_get(struct json_object* jso, const char *key)
+{
+	struct json_object *result = NULL;
+	json_object_object_get_ex(jso, key, &result);
+	return result;
+}
+
+json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
+{
+	if (value != NULL)
+		*value = NULL;
+
+	if (NULL == jso)
+		return FALSE;
+
+	switch(jso->o_type)
+	{
+	case json_type_object:
+		return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
+	default:
+		if (value != NULL)
+			*value = NULL;
+		return FALSE;
+	}
+}
+
+void json_object_object_del(struct json_object* jso, const char *key)
+{
+	lh_table_delete(jso->o.c_object, key);
+}
+
+
+/* json_object_boolean */
+
+static int json_object_boolean_to_json_string(struct json_object* jso,
+					      struct printbuf *pb,
+					      int level,
+						  int flags)
+{
+  if(jso->o.c_boolean) return sprintbuf(pb, "true");
+  else return sprintbuf(pb, "false");
+}
+
+struct json_object* json_object_new_boolean(json_bool b)
+{
+  struct json_object *jso = json_object_new(json_type_boolean);
+  if(!jso) return NULL;
+  jso->_to_json_string = &json_object_boolean_to_json_string;
+  jso->o.c_boolean = b;
+  return jso;
+}
+
+json_bool json_object_get_boolean(struct json_object *jso)
+{
+  if(!jso) return FALSE;
+  switch(jso->o_type) {
+  case json_type_boolean:
+    return jso->o.c_boolean;
+  case json_type_int:
+    return (jso->o.c_int64 != 0);
+  case json_type_double:
+    return (jso->o.c_double != 0);
+  case json_type_string:
+    return (jso->o.c_string.len != 0);
+  default:
+    return FALSE;
+  }
+}
+
+
+/* json_object_int */
+
+static int json_object_int_to_json_string(struct json_object* jso,
+					  struct printbuf *pb,
+					  int level,
+					  int flags)
+{
+  return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
+}
+
+struct json_object* json_object_new_int(int32_t i)
+{
+  struct json_object *jso = json_object_new(json_type_int);
+  if(!jso) return NULL;
+  jso->_to_json_string = &json_object_int_to_json_string;
+  jso->o.c_int64 = i;
+  return jso;
+}
+
+int32_t json_object_get_int(struct json_object *jso)
+{
+  int64_t cint64;
+  enum json_type o_type;
+
+  if(!jso) return 0;
+
+  o_type = jso->o_type;
+  cint64 = jso->o.c_int64;
+
+  if (o_type == json_type_string)
+  {
+	/*
+	 * Parse strings into 64-bit numbers, then use the
+	 * 64-to-32-bit number handling below.
+	 */
+	if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
+		return 0; /* whoops, it didn't work. */
+	o_type = json_type_int;
+  }
+
+  switch(o_type) {
+  case json_type_int:
+	/* Make sure we return the correct values for out of range numbers. */
+	if (cint64 <= INT32_MIN)
+		return INT32_MIN;
+	else if (cint64 >= INT32_MAX)
+		return INT32_MAX;
+	else
+		return (int32_t)cint64;
+  case json_type_double:
+    return (int32_t)jso->o.c_double;
+  case json_type_boolean:
+    return jso->o.c_boolean;
+  default:
+    return 0;
+  }
+}
+
+struct json_object* json_object_new_int64(int64_t i)
+{
+  struct json_object *jso = json_object_new(json_type_int);
+  if(!jso) return NULL;
+  jso->_to_json_string = &json_object_int_to_json_string;
+  jso->o.c_int64 = i;
+  return jso;
+}
+
+int64_t json_object_get_int64(struct json_object *jso)
+{
+   int64_t cint;
+
+  if(!jso) return 0;
+  switch(jso->o_type) {
+  case json_type_int:
+    return jso->o.c_int64;
+  case json_type_double:
+    return (int64_t)jso->o.c_double;
+  case json_type_boolean:
+    return jso->o.c_boolean;
+  case json_type_string:
+	if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
+  default:
+    return 0;
+  }
+}
+
+
+/* json_object_double */
+
+static int json_object_double_to_json_string(struct json_object* jso,
+					     struct printbuf *pb,
+					     int level,
+						 int flags)
+{
+  char buf[128], *p, *q;
+  int size;
+  /* Although JSON RFC does not support
+     NaN or Infinity as numeric values
+     ECMA 262 section 9.8.1 defines
+     how to handle these cases as strings */
+  if(isnan(jso->o.c_double))
+    size = snprintf(buf, sizeof(buf), "NaN");
+  else if(isinf(jso->o.c_double))
+    if(jso->o.c_double > 0)
+      size = snprintf(buf, sizeof(buf), "Infinity");
+    else
+      size = snprintf(buf, sizeof(buf), "-Infinity");
+  else
+    size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double);
+
+  p = strchr(buf, ',');
+  if (p) {
+    *p = '.';
+  } else {
+    p = strchr(buf, '.');
+  }
+  if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
+    /* last useful digit, always keep 1 zero */
+    p++;
+    for (q=p ; *q ; q++) {
+      if (*q!='0') p=q;
+    }
+    /* drop trailing zeroes */
+    *(++p) = 0;
+    size = p-buf;
+  }
+  printbuf_memappend(pb, buf, size);
+  return size;
+}
+
+struct json_object* json_object_new_double(double d)
+{
+	struct json_object *jso = json_object_new(json_type_double);
+	if (!jso)
+		return NULL;
+	jso->_to_json_string = &json_object_double_to_json_string;
+	jso->o.c_double = d;
+	return jso;
+}
+
+struct json_object* json_object_new_double_s(double d, const char *ds)
+{
+	struct json_object *jso = json_object_new_double(d);
+	if (!jso)
+		return NULL;
+
+	json_object_set_serializer(jso, json_object_userdata_to_json_string,
+	    strdup(ds), json_object_free_userdata);
+	return jso;
+}
+
+int json_object_userdata_to_json_string(struct json_object *jso,
+	struct printbuf *pb, int level, int flags)
+{
+	int userdata_len = strlen(jso->_userdata);
+	printbuf_memappend(pb, jso->_userdata, userdata_len);
+	return userdata_len;
+}
+
+void json_object_free_userdata(struct json_object *jso, void *userdata)
+{
+	free(userdata);
+}
+
+double json_object_get_double(struct json_object *jso)
+{
+  double cdouble;
+  char *errPtr = NULL;
+
+  if(!jso) return 0.0;
+  switch(jso->o_type) {
+  case json_type_double:
+    return jso->o.c_double;
+  case json_type_int:
+    return jso->o.c_int64;
+  case json_type_boolean:
+    return jso->o.c_boolean;
+  case json_type_string:
+    errno = 0;
+    cdouble = strtod(jso->o.c_string.str,&errPtr);
+
+    /* if conversion stopped at the first character, return 0.0 */
+    if (errPtr == jso->o.c_string.str)
+        return 0.0;
+
+    /*
+     * Check that the conversion terminated on something sensible
+     *
+     * For example, { "pay" : 123AB } would parse as 123.
+     */
+    if (*errPtr != '\0')
+        return 0.0;
+
+    /*
+     * If strtod encounters a string which would exceed the
+     * capacity of a double, it returns +/- HUGE_VAL and sets
+     * errno to ERANGE. But +/- HUGE_VAL is also a valid result
+     * from a conversion, so we need to check errno.
+     *
+     * Underflow also sets errno to ERANGE, but it returns 0 in
+     * that case, which is what we will return anyway.
+     *
+     * See CERT guideline ERR30-C
+     */
+    if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
+        (ERANGE == errno))
+            cdouble = 0.0;
+    return cdouble;
+  default:
+    return 0.0;
+  }
+}
+
+
+/* json_object_string */
+
+static int json_object_string_to_json_string(struct json_object* jso,
+					     struct printbuf *pb,
+					     int level,
+						 int flags)
+{
+  sprintbuf(pb, "\"");
+  json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
+  sprintbuf(pb, "\"");
+  return 0;
+}
+
+static void json_object_string_delete(struct json_object* jso)
+{
+  free(jso->o.c_string.str);
+  json_object_generic_delete(jso);
+}
+
+struct json_object* json_object_new_string(const char *s)
+{
+  struct json_object *jso = json_object_new(json_type_string);
+  if(!jso) return NULL;
+  jso->_delete = &json_object_string_delete;
+  jso->_to_json_string = &json_object_string_to_json_string;
+  jso->o.c_string.str = strdup(s);
+  jso->o.c_string.len = strlen(s);
+  return jso;
+}
+
+struct json_object* json_object_new_string_len(const char *s, int len)
+{
+  struct json_object *jso = json_object_new(json_type_string);
+  if(!jso) return NULL;
+  jso->_delete = &json_object_string_delete;
+  jso->_to_json_string = &json_object_string_to_json_string;
+  jso->o.c_string.str = (char*)malloc(len + 1);
+  memcpy(jso->o.c_string.str, (void *)s, len);
+  jso->o.c_string.str[len] = '\0';
+  jso->o.c_string.len = len;
+  return jso;
+}
+
+const char* json_object_get_string(struct json_object *jso)
+{
+  if(!jso) return NULL;
+  switch(jso->o_type) {
+  case json_type_string:
+    return jso->o.c_string.str;
+  default:
+    return json_object_to_json_string(jso);
+  }
+}
+
+int json_object_get_string_len(struct json_object *jso)  {
+  if(!jso) return 0;
+  switch(jso->o_type) {
+  case json_type_string:
+    return jso->o.c_string.len;
+  default:
+    return 0;
+  }
+}
+
+
+/* json_object_array */
+
+static int json_object_array_to_json_string(struct json_object* jso,
+                                            struct printbuf *pb,
+                                            int level,
+                                            int flags)
+{
+	int had_children = 0;
+	int ii;
+	sprintbuf(pb, "[");
+	if (flags & JSON_C_TO_STRING_PRETTY)
+		sprintbuf(pb, "\n");
+	for(ii=0; ii < json_object_array_length(jso); ii++)
+	{
+		struct json_object *val;
+		if (had_children)
+		{
+			sprintbuf(pb, ",");
+			if (flags & JSON_C_TO_STRING_PRETTY)
+				sprintbuf(pb, "\n");
+		}
+		had_children = 1;
+		if (flags & JSON_C_TO_STRING_SPACED)
+			sprintbuf(pb, " ");
+		indent(pb, level + 1, flags);
+		val = json_object_array_get_idx(jso, ii);
+		if(val == NULL)
+			sprintbuf(pb, "null");
+		else
+			val->_to_json_string(val, pb, level+1, flags);
+	}
+	if (flags & JSON_C_TO_STRING_PRETTY)
+	{
+		if (had_children)
+			sprintbuf(pb, "\n");
+		indent(pb,level,flags);
+	}
+
+	if (flags & JSON_C_TO_STRING_SPACED)
+		return sprintbuf(pb, " ]");
+	else
+		return sprintbuf(pb, "]");
+}
+
+static void json_object_array_entry_free(void *data)
+{
+  json_object_put((struct json_object*)data);
+}
+
+static void json_object_array_delete(struct json_object* jso)
+{
+  array_list_free(jso->o.c_array);
+  json_object_generic_delete(jso);
+}
+
+struct json_object* json_object_new_array(void)
+{
+  struct json_object *jso = json_object_new(json_type_array);
+  if(!jso) return NULL;
+  jso->_delete = &json_object_array_delete;
+  jso->_to_json_string = &json_object_array_to_json_string;
+  jso->o.c_array = array_list_new(&json_object_array_entry_free);
+  return jso;
+}
+
+struct array_list* json_object_get_array(struct json_object *jso)
+{
+  if(!jso) return NULL;
+  switch(jso->o_type) {
+  case json_type_array:
+    return jso->o.c_array;
+  default:
+    return NULL;
+  }
+}
+
+void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
+{
+  array_list_sort(jso->o.c_array, sort_fn);
+}
+
+int json_object_array_length(struct json_object *jso)
+{
+  return array_list_length(jso->o.c_array);
+}
+
+int json_object_array_add(struct json_object *jso,struct json_object *val)
+{
+  return array_list_add(jso->o.c_array, val);
+}
+
+int json_object_array_put_idx(struct json_object *jso, int idx,
+			      struct json_object *val)
+{
+  return array_list_put_idx(jso->o.c_array, idx, val);
+}
+
+struct json_object* json_object_array_get_idx(struct json_object *jso,
+					      int idx)
+{
+  return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
+}
+
diff --git a/modules/kazoo/deps/json_object.h b/modules/kazoo/deps/json_object.h
new file mode 100644
index 0000000..200ac40
--- /dev/null
+++ b/modules/kazoo/deps/json_object.h
@@ -0,0 +1,612 @@
+/*
+ * $Id: json_object.h,v 1.12 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_object_h_
+#define _json_object_h_
+
+#ifdef __GNUC__
+#define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func
+#else
+#define THIS_FUNCTION_IS_DEPRECATED(func) func
+#endif
+
+#include "json_inttypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define JSON_OBJECT_DEF_HASH_ENTRIES 16
+
+/**
+ * A flag for the json_object_to_json_string_ext() and
+ * json_object_to_file_ext() functions which causes the output
+ * to have no extra whitespace or formatting applied.
+ */
+#define JSON_C_TO_STRING_PLAIN      0
+/**
+ * A flag for the json_object_to_json_string_ext() and
+ * json_object_to_file_ext() functions which causes the output to have
+ * minimal whitespace inserted to make things slightly more readable.
+ */
+#define JSON_C_TO_STRING_SPACED     (1<<0)
+/**
+ * A flag for the json_object_to_json_string_ext() and
+ * json_object_to_file_ext() functions which causes
+ * the output to be formatted.
+ *
+ * See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/
+ * for an example of the format.
+ */
+#define JSON_C_TO_STRING_PRETTY     (1<<1)
+/**
+ * A flag to drop trailing zero for float values
+ */
+#define JSON_C_TO_STRING_NOZERO     (1<<2)
+
+#undef FALSE
+#define FALSE ((json_bool)0)
+
+#undef TRUE
+#define TRUE ((json_bool)1)
+
+extern const char *json_number_chars;
+extern const char *json_hex_chars;
+
+/* CAW: added for ANSI C iteration correctness */
+struct json_object_iter
+{
+	char *key;
+	struct json_object *val;
+	struct lh_entry *entry;
+};
+
+/* forward structure definitions */
+
+typedef int json_bool;
+typedef struct printbuf printbuf;
+typedef struct lh_table lh_table;
+typedef struct array_list array_list;
+typedef struct json_object json_object;
+typedef struct json_object_iter json_object_iter;
+typedef struct json_tokener json_tokener;
+
+/**
+ * Type of custom user delete functions.  See json_object_set_serializer.
+ */
+typedef void (json_object_delete_fn)(struct json_object *jso, void *userdata);
+
+/**
+ * Type of a custom serialization function.  See json_object_set_serializer.
+ */
+typedef int (json_object_to_json_string_fn)(struct json_object *jso,
+						struct printbuf *pb,
+						int level,
+						int flags);
+
+/* supported object types */
+
+typedef enum json_type {
+  /* If you change this, be sure to update json_type_to_name() too */
+  json_type_null,
+  json_type_boolean,
+  json_type_double,
+  json_type_int,
+  json_type_object,
+  json_type_array,
+  json_type_string,
+} json_type;
+
+/* reference counting functions */
+
+/**
+ * Increment the reference count of json_object, thereby grabbing shared 
+ * ownership of obj.
+ *
+ * @param obj the json_object instance
+ */
+extern struct json_object* json_object_get(struct json_object *obj);
+
+/**
+ * Decrement the reference count of json_object and free if it reaches zero.
+ * You must have ownership of obj prior to doing this or you will cause an
+ * imbalance in the reference count.
+ *
+ * @param obj the json_object instance
+ * @returns 1 if the object was freed.
+ */
+int json_object_put(struct json_object *obj);
+
+/**
+ * Check if the json_object is of a given type
+ * @param obj the json_object instance
+ * @param type one of:
+     json_type_null (i.e. obj == NULL),
+     json_type_boolean,
+     json_type_double,
+     json_type_int,
+     json_type_object,
+     json_type_array,
+     json_type_string,
+ */
+extern int json_object_is_type(struct json_object *obj, enum json_type type);
+
+/**
+ * Get the type of the json_object.  See also json_type_to_name() to turn this
+ * into a string suitable, for instance, for logging.
+ *
+ * @param obj the json_object instance
+ * @returns type being one of:
+     json_type_null (i.e. obj == NULL),
+     json_type_boolean,
+     json_type_double,
+     json_type_int,
+     json_type_object,
+     json_type_array,
+     json_type_string,
+ */
+extern enum json_type json_object_get_type(struct json_object *obj);
+
+
+/** Stringify object to json format.
+ * Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
+ * @param obj the json_object instance
+ * @returns a string in JSON format
+ */
+extern const char* json_object_to_json_string(struct json_object *obj);
+
+/** Stringify object to json format
+ * @param obj the json_object instance
+ * @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants
+ * @returns a string in JSON format
+ */
+extern const char* json_object_to_json_string_ext(struct json_object *obj, int
+flags);
+
+/**
+ * Set a custom serialization function to be used when this particular object
+ * is converted to a string by json_object_to_json_string.
+ *
+ * If a custom serializer is already set on this object, any existing 
+ * user_delete function is called before the new one is set.
+ *
+ * If to_string_func is NULL, the other parameters are ignored
+ * and the default behaviour is reset.
+ *
+ * The userdata parameter is optional and may be passed as NULL.  If provided,
+ * it is passed to to_string_func as-is.  This parameter may be NULL even
+ * if user_delete is non-NULL.
+ *
+ * The user_delete parameter is optional and may be passed as NULL, even if
+ * the userdata parameter is non-NULL.  It will be called just before the
+ * json_object is deleted, after it's reference count goes to zero
+ * (see json_object_put()).
+ * If this is not provided, it is up to the caller to free the userdata at
+ * an appropriate time. (i.e. after the json_object is deleted)
+ *
+ * @param jso the object to customize
+ * @param to_string_func the custom serialization function
+ * @param userdata an optional opaque cookie
+ * @param user_delete an optional function from freeing userdata
+ */
+extern void json_object_set_serializer(json_object *jso,
+	json_object_to_json_string_fn to_string_func,
+	void *userdata,
+	json_object_delete_fn *user_delete);
+
+/**
+ * Simply call free on the userdata pointer.
+ * Can be used with json_object_set_serializer().
+ *
+ * @param jso unused
+ * @param userdata the pointer that is passed to free().
+ */
+json_object_delete_fn json_object_free_userdata;
+
+/**
+ * Copy the jso->_userdata string over to pb as-is.
+ * Can be used with json_object_set_serializer().
+ *
+ * @param jso The object whose _userdata is used.
+ * @param pb The destination buffer.
+ * @param level Ignored.
+ * @param flags Ignored.
+ */
+json_object_to_json_string_fn json_object_userdata_to_json_string;
+
+
+/* object type methods */
+
+/** Create a new empty object with a reference count of 1.  The caller of
+ * this object initially has sole ownership.  Remember, when using
+ * json_object_object_add or json_object_array_put_idx, ownership will
+ * transfer to the object/array.  Call json_object_get if you want to maintain
+ * shared ownership or also add this object as a child of multiple objects or
+ * arrays.  Any ownerships you acquired but did not transfer must be released
+ * through json_object_put.
+ *
+ * @returns a json_object of type json_type_object
+ */
+extern struct json_object* json_object_new_object(void);
+
+/** Get the hashtable of a json_object of type json_type_object
+ * @param obj the json_object instance
+ * @returns a linkhash
+ */
+extern struct lh_table* json_object_get_object(struct json_object *obj);
+
+/** Get the size of an object in terms of the number of fields it has.
+ * @param obj the json_object whose length to return
+ */
+extern int json_object_object_length(struct json_object* obj);
+
+/** Add an object field to a json_object of type json_type_object
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object, independent of the lifetime of obj, you must wrap the
+ * passed object with json_object_get.
+ *
+ * Upon calling this, the ownership of val transfers to obj.  Thus you must
+ * make sure that you do in fact have ownership over this object.  For instance,
+ * json_object_new_object will give you ownership until you transfer it,
+ * whereas json_object_object_get does not.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name (a private copy will be duplicated)
+ * @param val a json_object or NULL member to associate with the given field
+ */
+extern void json_object_object_add(struct json_object* obj, const char *key,
+				   struct json_object *val);
+
+/** Get the json_object associate with a given object field
+ *
+ * *No* reference counts will be changed.  There is no need to manually adjust
+ * reference counts through the json_object_put/json_object_get methods unless
+ * you need to have the child (value) reference maintain a different lifetime
+ * than the owning parent (obj). Ownership of the returned value is retained
+ * by obj (do not do json_object_put unless you have done a json_object_get).
+ * If you delete the value from obj (json_object_object_del) and wish to access
+ * the returned reference afterwards, make sure you have first gotten shared
+ * ownership through json_object_get (& don't forget to do a json_object_put
+ * or transfer ownership to prevent a memory leak).
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ * @returns the json_object associated with the given field name
+ * @deprecated Please use json_object_object_get_ex
+ */
+THIS_FUNCTION_IS_DEPRECATED(extern struct json_object* json_object_object_get(struct json_object* obj,
+						  const char *key));
+
+/** Get the json_object associated with a given object field.  
+ *
+ * This returns true if the key is found, false in all other cases (including 
+ * if obj isn't a json_type_object).
+ *
+ * *No* reference counts will be changed.  There is no need to manually adjust
+ * reference counts through the json_object_put/json_object_get methods unless
+ * you need to have the child (value) reference maintain a different lifetime
+ * than the owning parent (obj).  Ownership of value is retained by obj.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ * @param value a pointer where to store a reference to the json_object 
+ *              associated with the given field name.
+ *
+ *              It is safe to pass a NULL value.
+ * @returns whether or not the key exists
+ */
+extern json_bool json_object_object_get_ex(struct json_object* obj,
+						  const char *key,
+                                                  struct json_object **value);
+
+/** Delete the given json_object field
+ *
+ * The reference count will be decremented for the deleted object.  If there
+ * are no more owners of the value represented by this key, then the value is
+ * freed.  Otherwise, the reference to the value will remain in memory.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ */
+extern void json_object_object_del(struct json_object* obj, const char *key);
+
+/**
+ * Iterate through all keys and values of an object.
+ *
+ * Adding keys to the object while iterating is NOT allowed.
+ *
+ * Deleting an existing key, or replacing an existing key with a
+ * new value IS allowed.
+ *
+ * @param obj the json_object instance
+ * @param key the local name for the char* key variable defined in the body
+ * @param val the local name for the json_object* object variable defined in
+ *            the body
+ */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L
+
+# define json_object_object_foreach(obj,key,val) \
+	char *key; \
+	struct json_object *val __attribute__((__unused__)); \
+	for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
+		({ if(entry ## key) { \
+			key = (char*)entry ## key->k; \
+			val = (struct json_object*)entry ## key->v; \
+			entry_next ## key = entry ## key->next; \
+		} ; entry ## key; }); \
+		entry ## key = entry_next ## key )
+
+#else /* ANSI C or MSC */
+
+# define json_object_object_foreach(obj,key,val) \
+	char *key;\
+	struct json_object *val; \
+	struct lh_entry *entry ## key; \
+	struct lh_entry *entry_next ## key = NULL; \
+	for(entry ## key = json_object_get_object(obj)->head; \
+		(entry ## key ? ( \
+			key = (char*)entry ## key->k, \
+			val = (struct json_object*)entry ## key->v, \
+			entry_next ## key = entry ## key->next, \
+			entry ## key) : 0); \
+		entry ## key = entry_next ## key)
+
+#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */
+
+/** Iterate through all keys and values of an object (ANSI C Safe)
+ * @param obj the json_object instance
+ * @param iter the object iterator
+ */
+#define json_object_object_foreachC(obj,iter) \
+ for(iter.entry = json_object_get_object(obj)->head; (iter.entry ? (iter.key = (char*)iter.entry->k, iter.val = (struct json_object*)iter.entry->v, iter.entry) : 0); iter.entry = iter.entry->next)
+
+/* Array type methods */
+
+/** Create a new empty json_object of type json_type_array
+ * @returns a json_object of type json_type_array
+ */
+extern struct json_object* json_object_new_array(void);
+
+/** Get the arraylist of a json_object of type json_type_array
+ * @param obj the json_object instance
+ * @returns an arraylist
+ */
+extern struct array_list* json_object_get_array(struct json_object *obj);
+
+/** Get the length of a json_object of type json_type_array
+ * @param obj the json_object instance
+ * @returns an int
+ */
+extern int json_object_array_length(struct json_object *obj);
+
+/** Sorts the elements of jso of type json_type_array
+*
+* Pointers to the json_object pointers will be passed as the two arguments
+* to @sort_fn
+*
+* @param obj the json_object instance
+* @param sort_fn a sorting function
+*/
+extern void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *));
+
+/** Add an element to the end of a json_object of type json_type_array
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * @param obj the json_object instance
+ * @param val the json_object to be added
+ */
+extern int json_object_array_add(struct json_object *obj,
+				 struct json_object *val);
+
+/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array)
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * The reference count of a replaced object will be decremented.
+ *
+ * The array size will be automatically be expanded to the size of the
+ * index if the index is larger than the current size.
+ *
+ * @param obj the json_object instance
+ * @param idx the index to insert the element at
+ * @param val the json_object to be added
+ */
+extern int json_object_array_put_idx(struct json_object *obj, int idx,
+				     struct json_object *val);
+
+/** Get the element at specificed index of the array (a json_object of type json_type_array)
+ * @param obj the json_object instance
+ * @param idx the index to get the element at
+ * @returns the json_object at the specified index (or NULL)
+ */
+extern struct json_object* json_object_array_get_idx(struct json_object *obj,
+						     int idx);
+
+/* json_bool type methods */
+
+/** Create a new empty json_object of type json_type_boolean
+ * @param b a json_bool TRUE or FALSE (0 or 1)
+ * @returns a json_object of type json_type_boolean
+ */
+extern struct json_object* json_object_new_boolean(json_bool b);
+
+/** Get the json_bool value of a json_object
+ *
+ * The type is coerced to a json_bool if the passed object is not a json_bool.
+ * integer and double objects will return FALSE if there value is zero
+ * or TRUE otherwise. If the passed object is a string it will return
+ * TRUE if it has a non zero length. If any other object type is passed
+ * TRUE will be returned if the object is not NULL.
+ *
+ * @param obj the json_object instance
+ * @returns a json_bool
+ */
+extern json_bool json_object_get_boolean(struct json_object *obj);
+
+
+/* int type methods */
+
+/** Create a new empty json_object of type json_type_int
+ * Note that values are stored as 64-bit values internally.
+ * To ensure the full range is maintained, use json_object_new_int64 instead.
+ * @param i the integer
+ * @returns a json_object of type json_type_int
+ */
+extern struct json_object* json_object_new_int(int32_t i);
+
+
+/** Create a new empty json_object of type json_type_int
+ * @param i the integer
+ * @returns a json_object of type json_type_int
+ */
+extern struct json_object* json_object_new_int64(int64_t i);
+
+
+/** Get the int value of a json_object
+ *
+ * The type is coerced to a int if the passed object is not a int.
+ * double objects will return their integer conversion. Strings will be
+ * parsed as an integer. If no conversion exists then 0 is returned
+ * and errno is set to EINVAL. null is equivalent to 0 (no error values set)
+ *
+ * Note that integers are stored internally as 64-bit values.
+ * If the value of too big or too small to fit into 32-bit, INT32_MAX or
+ * INT32_MIN are returned, respectively.
+ *
+ * @param obj the json_object instance
+ * @returns an int
+ */
+extern int32_t json_object_get_int(struct json_object *obj);
+
+/** Get the int value of a json_object
+ *
+ * The type is coerced to a int64 if the passed object is not a int64.
+ * double objects will return their int64 conversion. Strings will be
+ * parsed as an int64. If no conversion exists then 0 is returned.
+ *
+ * NOTE: Set errno to 0 directly before a call to this function to determine
+ * whether or not conversion was successful (it does not clear the value for
+ * you).
+ *
+ * @param obj the json_object instance
+ * @returns an int64
+ */
+extern int64_t json_object_get_int64(struct json_object *obj);
+
+
+/* double type methods */
+
+/** Create a new empty json_object of type json_type_double
+ * @param d the double
+ * @returns a json_object of type json_type_double
+ */
+extern struct json_object* json_object_new_double(double d);
+
+/**
+ * Create a new json_object of type json_type_double, using
+ * the exact serialized representation of the value.
+ *
+ * This allows for numbers that would otherwise get displayed
+ * inefficiently (e.g. 12.3 => "12.300000000000001") to be
+ * serialized with the more convenient form.
+ *
+ * Note: this is used by json_tokener_parse_ex() to allow for
+ *   an exact re-serialization of a parsed object.
+ *
+ * An equivalent sequence of calls is:
+ * @code
+ *   jso = json_object_new_double(d);
+ *   json_object_set_serializer(d, json_object_userdata_to_json_string,
+ *       strdup(ds), json_object_free_userdata)
+ * @endcode
+ *
+ * @param d the numeric value of the double.
+ * @param ds the string representation of the double.  This will be copied.
+ */
+extern struct json_object* json_object_new_double_s(double d, const char *ds);
+
+/** Get the double floating point value of a json_object
+ *
+ * The type is coerced to a double if the passed object is not a double.
+ * integer objects will return their double conversion. Strings will be
+ * parsed as a double. If no conversion exists then 0.0 is returned and
+ * errno is set to EINVAL. null is equivalent to 0 (no error values set)
+ *
+ * If the value is too big to fit in a double, then the value is set to
+ * the closest infinity with errno set to ERANGE. If strings cannot be
+ * converted to their double value, then EINVAL is set & NaN is returned.
+ *
+ * Arrays of length 0 are interpreted as 0 (with no error flags set).
+ * Arrays of length 1 are effectively cast to the equivalent object and
+ * converted using the above rules.  All other arrays set the error to
+ * EINVAL & return NaN.
+ *
+ * NOTE: Set errno to 0 directly before a call to this function to
+ * determine whether or not conversion was successful (it does not clear
+ * the value for you).
+ *
+ * @param obj the json_object instance
+ * @returns a double floating point number
+ */
+extern double json_object_get_double(struct json_object *obj);
+
+
+/* string type methods */
+
+/** Create a new empty json_object of type json_type_string
+ *
+ * A copy of the string is made and the memory is managed by the json_object
+ *
+ * @param s the string
+ * @returns a json_object of type json_type_string
+ */
+extern struct json_object* json_object_new_string(const char *s);
+
+extern struct json_object* json_object_new_string_len(const char *s, int len);
+
+/** Get the string value of a json_object
+ *
+ * If the passed object is not of type json_type_string then the JSON
+ * representation of the object is returned.
+ *
+ * The returned string memory is managed by the json_object and will
+ * be freed when the reference count of the json_object drops to zero.
+ *
+ * @param obj the json_object instance
+ * @returns a string
+ */
+extern const char* json_object_get_string(struct json_object *obj);
+
+/** Get the string length of a json_object
+ *
+ * If the passed object is not of type json_type_string then zero
+ * will be returned.
+ *
+ * @param obj the json_object instance
+ * @returns int
+ */
+extern int json_object_get_string_len(struct json_object *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/json_object_iterator.c b/modules/kazoo/deps/json_object_iterator.c
new file mode 100644
index 0000000..7066649
--- /dev/null
+++ b/modules/kazoo/deps/json_object_iterator.c
@@ -0,0 +1,168 @@
+/**
+*******************************************************************************
+* @file json_object_iterator.c
+*
+* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
+*
+* This library is free software; you can redistribute it and/or modify
+* it under the terms of the MIT license. See COPYING for details.
+*
+* @brief  json-c forces clients to use its private data
+*         structures for JSON Object iteration.  This API
+*         implementation corrects that by abstracting the
+*         private json-c details.
+*
+*******************************************************************************
+*/
+
+#include <stddef.h>
+
+#include "json.h"
+#include "json_object_private.h"
+
+#include "json_object_iterator.h"
+
+/**
+ * How It Works
+ *
+ * For each JSON Object, json-c maintains a linked list of zero
+ * or more lh_entry (link-hash entry) structures inside the
+ * Object's link-hash table (lh_table).
+ *
+ * Each lh_entry structure on the JSON Object's linked list
+ * represents a single name/value pair.  The "next" field of the
+ * last lh_entry in the list is set to NULL, which terminates
+ * the list.
+ *
+ * We represent a valid iterator that refers to an actual
+ * name/value pair via a pointer to the pair's lh_entry
+ * structure set as the iterator's opaque_ field.
+ *
+ * We follow json-c's current pair list representation by
+ * representing a valid "end" iterator (one that refers past the
+ * last pair) with a NULL value in the iterator's opaque_ field.
+ *
+ * A JSON Object without any pairs in it will have the "head"
+ * field of its lh_table structure set to NULL.  For such an
+ * object, json_object_iter_begin will return an iterator with
+ * the opaque_ field set to NULL, which is equivalent to the
+ * "end" iterator.
+ *
+ * When iterating, we simply update the iterator's opaque_ field
+ * to point to the next lh_entry structure in the linked list.
+ * opaque_ will become NULL once we iterate past the last pair
+ * in the list, which makes the iterator equivalent to the "end"
+ * iterator.
+ */
+
+/// Our current representation of the "end" iterator;
+///
+/// @note May not always be NULL
+static const void* kObjectEndIterValue = NULL;
+
+/**
+ * ****************************************************************************
+ */
+struct json_object_iterator
+json_object_iter_begin(struct json_object* obj)
+{
+    struct json_object_iterator iter;
+    struct lh_table* pTable;
+
+    /// @note json_object_get_object will return NULL if passed NULL
+    ///       or a non-json_type_object instance
+    pTable = json_object_get_object(obj);
+    JASSERT(NULL != pTable);
+
+    /// @note For a pair-less Object, head is NULL, which matches our
+    ///       definition of the "end" iterator
+    iter.opaque_ = pTable->head;
+    return iter;
+}
+
+/**
+ * ****************************************************************************
+ */
+struct json_object_iterator
+json_object_iter_end(const struct json_object* obj)
+{
+    struct json_object_iterator iter;
+
+    JASSERT(NULL != obj);
+    JASSERT(json_object_is_type(obj, json_type_object));
+
+    iter.opaque_ = kObjectEndIterValue;
+
+    return iter;
+}
+
+/**
+ * ****************************************************************************
+ */
+void
+json_object_iter_next(struct json_object_iterator* iter)
+{
+    JASSERT(NULL != iter);
+    JASSERT(kObjectEndIterValue != iter->opaque_);
+
+    iter->opaque_ = ((struct lh_entry *)iter->opaque_)->next;
+}
+
+
+/**
+ * ****************************************************************************
+ */
+const char*
+json_object_iter_peek_name(const struct json_object_iterator* iter)
+{
+    JASSERT(NULL != iter);
+    JASSERT(kObjectEndIterValue != iter->opaque_);
+
+    return (const char*)(((struct lh_entry *)iter->opaque_)->k);
+}
+
+
+/**
+ * ****************************************************************************
+ */
+struct json_object*
+json_object_iter_peek_value(const struct json_object_iterator* iter)
+{
+    JASSERT(NULL != iter);
+    JASSERT(kObjectEndIterValue != iter->opaque_);
+
+    return (struct json_object*)(((struct lh_entry *)iter->opaque_)->v);
+}
+
+
+/**
+ * ****************************************************************************
+ */
+json_bool
+json_object_iter_equal(const struct json_object_iterator* iter1,
+                       const struct json_object_iterator* iter2)
+{
+    JASSERT(NULL != iter1);
+    JASSERT(NULL != iter2);
+
+    return (iter1->opaque_ == iter2->opaque_);
+}
+
+
+/**
+ * ****************************************************************************
+ */
+struct json_object_iterator
+json_object_iter_init_default(void)
+{
+    struct json_object_iterator iter;
+
+    /**
+     * @note Make this a negative, invalid value, such that
+     *       accidental access to it would likely be trapped by the
+     *       hardware as an invalid address.
+     */
+    iter.opaque_ = NULL;
+
+    return iter;
+}
diff --git a/modules/kazoo/deps/json_object_iterator.h b/modules/kazoo/deps/json_object_iterator.h
new file mode 100644
index 0000000..44c9fb2
--- /dev/null
+++ b/modules/kazoo/deps/json_object_iterator.h
@@ -0,0 +1,239 @@
+/**
+*******************************************************************************
+* @file json_object_iterator.h
+*
+* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
+*
+* This library is free software; you can redistribute it and/or modify
+* it under the terms of the MIT license. See COPYING for details.
+*
+* @brief  json-c forces clients to use its private data
+*         structures for JSON Object iteration.  This API
+*         corrects that by abstracting the private json-c
+*         details.
+*
+* API attributes: <br>
+*   * Thread-safe: NO<br>
+*   * Reentrant: NO
+*
+*******************************************************************************
+*/
+
+
+#ifndef JSON_OBJECT_ITERATOR_H
+#define JSON_OBJECT_ITERATOR_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Forward declaration for the opaque iterator information.
+ */
+struct json_object_iter_info_;
+
+/**
+ * The opaque iterator that references a name/value pair within
+ * a JSON Object instance or the "end" iterator value.
+ */
+struct json_object_iterator {
+    const void* opaque_;
+};
+
+
+/**
+ * forward declaration of json-c's JSON value instance structure
+ */
+struct json_object;
+
+
+/**
+ * Initializes an iterator structure to a "default" value that
+ * is convenient for initializing an iterator variable to a
+ * default state (e.g., initialization list in a class'
+ * constructor).
+ *
+ * @code
+ * struct json_object_iterator iter = json_object_iter_init_default();
+ * MyClass() : iter_(json_object_iter_init_default())
+ * @endcode
+ *
+ * @note The initialized value doesn't reference any specific
+ *       pair, is considered an invalid iterator, and MUST NOT
+ *       be passed to any json-c API that expects a valid
+ *       iterator.
+ *
+ * @note User and internal code MUST NOT make any assumptions
+ *       about and dependencies on the value of the "default"
+ *       iterator value.
+ *
+ * @return json_object_iterator
+ */
+struct json_object_iterator
+json_object_iter_init_default(void);
+
+/** Retrieves an iterator to the first pair of the JSON Object.
+ *
+ * @warning 	Any modification of the underlying pair invalidates all
+ * 		iterators to that pair.
+ *
+ * @param obj	JSON Object instance (MUST be of type json_object)
+ *
+ * @return json_object_iterator If the JSON Object has at
+ *              least one pair, on return, the iterator refers
+ *              to the first pair. If the JSON Object doesn't
+ *              have any pairs, the returned iterator is
+ *              equivalent to the "end" iterator for the same
+ *              JSON Object instance.
+ *
+ * @code
+ * struct json_object_iterator it;
+ * struct json_object_iterator itEnd;
+ * struct json_object* obj;
+ *
+ * obj = json_tokener_parse("{'first':'george', 'age':100}");
+ * it = json_object_iter_begin(obj);
+ * itEnd = json_object_iter_end(obj);
+ *
+ * while (!json_object_iter_equal(&it, &itEnd)) {
+ *     printf("%s\n",
+ *            json_object_iter_peek_name(&it));
+ *     json_object_iter_next(&it);
+ * }
+ *
+ * @endcode
+ */
+struct json_object_iterator
+json_object_iter_begin(struct json_object* obj);
+
+/** Retrieves the iterator that represents the position beyond the
+ *  last pair of the given JSON Object instance.
+ *
+ *  @warning Do NOT write code that assumes that the "end"
+ *        iterator value is NULL, even if it is so in a
+ *        particular instance of the implementation.
+ *
+ *  @note The reason we do not (and MUST NOT) provide
+ *        "json_object_iter_is_end(json_object_iterator* iter)"
+ *        type of API is because it would limit the underlying
+ *        representation of name/value containment (or force us
+ *        to add additional, otherwise unnecessary, fields to
+ *        the iterator structure). The "end" iterator and the
+ *        equality test method, on the other hand, permit us to
+ *        cleanly abstract pretty much any reasonable underlying
+ *        representation without burdening the iterator
+ *        structure with unnecessary data.
+ *
+ *  @note For performance reasons, memorize the "end" iterator prior
+ *        to any loop.
+ *
+ * @param obj JSON Object instance (MUST be of type json_object)
+ *
+ * @return json_object_iterator On return, the iterator refers
+ *              to the "end" of the Object instance's pairs
+ *              (i.e., NOT the last pair, but "beyond the last
+ *              pair" value)
+ */
+struct json_object_iterator
+json_object_iter_end(const struct json_object* obj);
+
+/** Returns an iterator to the next pair, if any
+ *
+ * @warning	Any modification of the underlying pair
+ *       	invalidates all iterators to that pair.
+ *
+ * @param iter [IN/OUT] Pointer to iterator that references a
+ *         name/value pair; MUST be a valid, non-end iterator.
+ *         WARNING: bad things will happen if invalid or "end"
+ *         iterator is passed. Upon return will contain the
+ *         reference to the next pair if there is one; if there
+ *         are no more pairs, will contain the "end" iterator
+ *         value, which may be compared against the return value
+ *         of json_object_iter_end() for the same JSON Object
+ *         instance.
+ */
+void
+json_object_iter_next(struct json_object_iterator* iter);
+
+
+/** Returns a const pointer to the name of the pair referenced
+ *  by the given iterator.
+ *
+ * @param iter pointer to iterator that references a name/value
+ *             pair; MUST be a valid, non-end iterator.
+ *
+ * @warning	bad things will happen if an invalid or
+ *             	"end" iterator is passed.
+ *
+ * @return const char* Pointer to the name of the referenced
+ *         name/value pair.  The name memory belongs to the
+ *         name/value pair, will be freed when the pair is
+ *         deleted or modified, and MUST NOT be modified or
+ *         freed by the user.
+ */
+const char*
+json_object_iter_peek_name(const struct json_object_iterator* iter);
+
+
+/** Returns a pointer to the json-c instance representing the
+ *  value of the referenced name/value pair, without altering
+ *  the instance's reference count.
+ *
+ * @param iter 	pointer to iterator that references a name/value
+ *             	pair; MUST be a valid, non-end iterator.
+ *
+ * @warning	bad things will happen if invalid or
+ *             "end" iterator is passed.
+ *
+ * @return struct json_object* Pointer to the json-c value
+ *         instance of the referenced name/value pair;  the
+ *         value's reference count is not changed by this
+ *         function: if you plan to hold on to this json-c node,
+ *         take a look at json_object_get() and
+ *         json_object_put(). IMPORTANT: json-c API represents
+ *         the JSON Null value as a NULL json_object instance
+ *         pointer.
+ */
+struct json_object*
+json_object_iter_peek_value(const struct json_object_iterator* iter);
+
+
+/** Tests two iterators for equality.  Typically used to test
+ *  for end of iteration by comparing an iterator to the
+ *  corresponding "end" iterator (that was derived from the same
+ *  JSON Object instance).
+ *
+ *  @note The reason we do not (and MUST NOT) provide
+ *        "json_object_iter_is_end(json_object_iterator* iter)"
+ *        type of API is because it would limit the underlying
+ *        representation of name/value containment (or force us
+ *        to add additional, otherwise unnecessary, fields to
+ *        the iterator structure). The equality test method, on
+ *        the other hand, permits us to cleanly abstract pretty
+ *        much any reasonable underlying representation.
+ *
+ * @param iter1 Pointer to first valid, non-NULL iterator
+ * @param iter2 POinter to second valid, non-NULL iterator
+ *
+ * @warning	if a NULL iterator pointer or an uninitialized
+ *       	or invalid iterator, or iterators derived from
+ *       	different JSON Object instances are passed, bad things
+ *       	will happen!
+ *
+ * @return json_bool non-zero if iterators are equal (i.e., both
+ *         reference the same name/value pair or are both at
+ *         "end"); zero if they are not equal.
+ */
+json_bool
+json_object_iter_equal(const struct json_object_iterator* iter1,
+                       const struct json_object_iterator* iter2);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* JSON_OBJECT_ITERATOR_H */
diff --git a/modules/kazoo/deps/json_object_private.h b/modules/kazoo/deps/json_object_private.h
new file mode 100644
index 0000000..5ed791b
--- /dev/null
+++ b/modules/kazoo/deps/json_object_private.h
@@ -0,0 +1,47 @@
+/*
+ * $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_object_private_h_
+#define _json_object_private_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (json_object_private_delete_fn)(struct json_object *o);
+
+struct json_object
+{
+  enum json_type o_type;
+  json_object_private_delete_fn *_delete;
+  json_object_to_json_string_fn *_to_json_string;
+  int _ref_count;
+  struct printbuf *_pb;
+  union data {
+    json_bool c_boolean;
+    double c_double;
+    int64_t c_int64;
+    struct lh_table *c_object;
+    struct array_list *c_array;
+    struct {
+        char *str;
+        int len;
+    } c_string;
+  } o;
+  json_object_delete_fn *_user_delete;
+  void *_userdata;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/json_tokener.c b/modules/kazoo/deps/json_tokener.c
new file mode 100644
index 0000000..ed178c0
--- /dev/null
+++ b/modules/kazoo/deps/json_tokener.c
@@ -0,0 +1,888 @@
+/*
+ * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ *
+ * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
+ * The copyrights to the contents of this file are licensed under the MIT License
+ * (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+#include "arraylist.h"
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_util.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif /* HAVE_LOCALE_H */
+
+#if !HAVE_STRDUP && defined(_MSC_VER)
+  /* MSC has the version as _strdup */
+# define strdup _strdup
+#elif !HAVE_STRDUP
+# error You do not have strdup on your system.
+#endif /* HAVE_STRDUP */
+
+#if !HAVE_STRNCASECMP && defined(_MSC_VER)
+  /* MSC has the version as _strnicmp */
+# define strncasecmp _strnicmp
+#elif !HAVE_STRNCASECMP
+# error You do not have strncasecmp on your system.
+#endif /* HAVE_STRNCASECMP */
+
+/* Use C99 NAN by default; if not available, nan("") should work too. */
+#ifndef NAN
+#define NAN nan("")
+#endif /* !NAN */
+
+static const char json_null_str[] = "null";
+static const int json_null_str_len = sizeof(json_null_str) - 1;
+static const char json_inf_str[] = "Infinity";
+static const int json_inf_str_len = sizeof(json_inf_str) - 1;
+static const char json_nan_str[] = "NaN";
+static const int json_nan_str_len = sizeof(json_nan_str) - 1;
+static const char json_true_str[] = "true";
+static const int json_true_str_len = sizeof(json_true_str) - 1;
+static const char json_false_str[] = "false";
+static const int json_false_str_len = sizeof(json_false_str) - 1;
+
+static const char* json_tokener_errors[] = {
+  "success",
+  "continue",
+  "nesting too deep",
+  "unexpected end of data",
+  "unexpected character",
+  "null expected",
+  "boolean expected",
+  "number expected",
+  "array value separator ',' expected",
+  "quoted object property name expected",
+  "object property name separator ':' expected",
+  "object value separator ',' expected",
+  "invalid string sequence",
+  "expected comment",
+  "buffer size overflow"
+};
+
+const char *json_tokener_error_desc(enum json_tokener_error jerr)
+{
+	int jerr_int = (int)jerr;
+	if (jerr_int < 0 || jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
+		return "Unknown error, invalid json_tokener_error value passed to json_tokener_error_desc()";
+	return json_tokener_errors[jerr];
+}
+
+enum json_tokener_error json_tokener_get_error(json_tokener *tok)
+{
+	return tok->err;
+}
+
+/* Stuff for decoding unicode sequences */
+#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
+#define IS_LOW_SURROGATE(uc)  (((uc) & 0xFC00) == 0xDC00)
+#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
+static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
+
+struct json_tokener* json_tokener_new_ex(int depth)
+{
+  struct json_tokener *tok;
+
+  tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
+  if (!tok) return NULL;
+  tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
+  if (!tok->stack) {
+    free(tok);
+    return NULL;
+  }
+  tok->pb = printbuf_new();
+  tok->max_depth = depth;
+  json_tokener_reset(tok);
+  return tok;
+}
+
+struct json_tokener* json_tokener_new(void)
+{
+  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
+}
+
+void json_tokener_free(struct json_tokener *tok)
+{
+  json_tokener_reset(tok);
+  if (tok->pb) printbuf_free(tok->pb);
+  if (tok->stack) free(tok->stack);
+  free(tok);
+}
+
+static void json_tokener_reset_level(struct json_tokener *tok, int depth)
+{
+  tok->stack[depth].state = json_tokener_state_eatws;
+  tok->stack[depth].saved_state = json_tokener_state_start;
+  json_object_put(tok->stack[depth].current);
+  tok->stack[depth].current = NULL;
+  free(tok->stack[depth].obj_field_name);
+  tok->stack[depth].obj_field_name = NULL;
+}
+
+void json_tokener_reset(struct json_tokener *tok)
+{
+  int i;
+  if (!tok)
+    return;
+
+  for(i = tok->depth; i >= 0; i--)
+    json_tokener_reset_level(tok, i);
+  tok->depth = 0;
+  tok->err = json_tokener_success;
+}
+
+struct json_object* json_tokener_parse(const char *str)
+{
+    enum json_tokener_error jerr_ignored;
+    struct json_object* obj;
+    obj = json_tokener_parse_verbose(str, &jerr_ignored);
+    return obj;
+}
+
+struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
+{
+    struct json_tokener* tok;
+    struct json_object* obj;
+
+    tok = json_tokener_new();
+    if (!tok)
+      return NULL;
+    obj = json_tokener_parse_ex(tok, str, -1);
+    *error = tok->err;
+    if(tok->err != json_tokener_success) {
+		if (obj != NULL)
+			json_object_put(obj);
+        obj = NULL;
+    }
+
+    json_tokener_free(tok);
+    return obj;
+}
+
+#define state  tok->stack[tok->depth].state
+#define saved_state  tok->stack[tok->depth].saved_state
+#define current tok->stack[tok->depth].current
+#define obj_field_name tok->stack[tok->depth].obj_field_name
+
+/* Optimization:
+ * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
+ * iterating character-by character.  A large performance boost is
+ * achieved by using tighter loops to locally handle units such as
+ * comments and strings.  Loops that handle an entire token within
+ * their scope also gather entire strings and pass them to
+ * printbuf_memappend() in a single call, rather than calling
+ * printbuf_memappend() one char at a time.
+ *
+ * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
+ * common to both the main loop and the tighter loops.
+ */
+
+/* PEEK_CHAR(dest, tok) macro:
+ *   Peeks at the current char and stores it in dest.
+ *   Returns 1 on success, sets tok->err and returns 0 if no more chars.
+ *   Implicit inputs:  str, len vars
+ */
+#define PEEK_CHAR(dest, tok)                                                  \
+  (((tok)->char_offset == len) ?                                          \
+   (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \
+    (((tok)->err = json_tokener_success), 0)                              \
+    :                                                                   \
+    (((tok)->err = json_tokener_continue), 0)                             \
+    ) :                                                                 \
+   (((dest) = *str), 1)                                                 \
+   )
+
+/* ADVANCE_CHAR() macro:
+ *   Incrementes str & tok->char_offset.
+ *   For convenience of existing conditionals, returns the old value of c (0 on eof)
+ *   Implicit inputs:  c var
+ */
+#define ADVANCE_CHAR(str, tok) \
+  ( ++(str), ((tok)->char_offset)++, c)
+
+
+/* End optimization macro defs */
+
+
+struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
+					  const char *str, int len)
+{
+  struct json_object *obj = NULL;
+  char c = '\1';
+#ifdef HAVE_SETLOCALE
+  char *oldlocale=NULL, *tmplocale;
+
+  tmplocale = setlocale(LC_NUMERIC, NULL);
+  if (tmplocale) oldlocale = strdup(tmplocale);
+  setlocale(LC_NUMERIC, "C");
+#endif
+
+  tok->char_offset = 0;
+  tok->err = json_tokener_success;
+
+  /* this interface is presently not 64-bit clean due to the int len argument
+     and the internal printbuf interface that takes 32-bit int len arguments
+     so the function limits the maximum string size to INT32_MAX (2GB).
+     If the function is called with len == -1 then strlen is called to check
+     the string length is less than INT32_MAX (2GB) */
+  if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
+    tok->err = json_tokener_error_size;
+    return NULL;
+  }
+
+  while (PEEK_CHAR(c, tok)) {
+
+  redo_char:
+    switch(state) {
+
+    case json_tokener_state_eatws:
+      /* Advance until we change state */
+      while (isspace((int)c)) {
+	if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
+	  goto out;
+      }
+      if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
+	printbuf_reset(tok->pb);
+	printbuf_memappend_fast(tok->pb, &c, 1);
+	state = json_tokener_state_comment_start;
+      } else {
+	state = saved_state;
+	goto redo_char;
+      }
+      break;
+
+    case json_tokener_state_start:
+      switch(c) {
+      case '{':
+	state = json_tokener_state_eatws;
+	saved_state = json_tokener_state_object_field_start;
+	current = json_object_new_object();
+	break;
+      case '[':
+	state = json_tokener_state_eatws;
+	saved_state = json_tokener_state_array;
+	current = json_object_new_array();
+	break;
+      case 'I':
+      case 'i':
+	state = json_tokener_state_inf;
+	printbuf_reset(tok->pb);
+	tok->st_pos = 0;
+	goto redo_char;
+      case 'N':
+      case 'n':
+	state = json_tokener_state_null; // or NaN
+	printbuf_reset(tok->pb);
+	tok->st_pos = 0;
+	goto redo_char;
+      case '\'':
+        if (tok->flags & JSON_TOKENER_STRICT) {
+            /* in STRICT mode only double-quote are allowed */
+            tok->err = json_tokener_error_parse_unexpected;
+            goto out;
+        }
+      case '"':
+	state = json_tokener_state_string;
+	printbuf_reset(tok->pb);
+	tok->quote_char = c;
+	break;
+      case 'T':
+      case 't':
+      case 'F':
+      case 'f':
+	state = json_tokener_state_boolean;
+	printbuf_reset(tok->pb);
+	tok->st_pos = 0;
+	goto redo_char;
+#if defined(__GNUC__)
+	  case '0' ... '9':
+#else
+	  case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+#endif
+      case '-':
+	state = json_tokener_state_number;
+	printbuf_reset(tok->pb);
+	tok->is_double = 0;
+	goto redo_char;
+      default:
+	tok->err = json_tokener_error_parse_unexpected;
+	goto out;
+      }
+      break;
+
+    case json_tokener_state_finish:
+      if(tok->depth == 0) goto out;
+      obj = json_object_get(current);
+      json_tokener_reset_level(tok, tok->depth);
+      tok->depth--;
+      goto redo_char;
+
+    case json_tokener_state_inf: /* aka starts with 'i' */
+      {
+//	int size;
+	int size_inf;
+	int is_negative = 0;
+
+	printbuf_memappend_fast(tok->pb, &c, 1);
+//	size = json_min(tok->st_pos+1, json_null_str_len);
+	size_inf = json_min(tok->st_pos+1, json_inf_str_len);
+	char *infbuf = tok->pb->buf;
+	if (*infbuf == '-')
+	{
+		infbuf++;
+		is_negative = 1;
+	}
+	if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+	          strncasecmp(json_inf_str, infbuf, size_inf) == 0) ||
+	         (strncmp(json_inf_str, infbuf, size_inf) == 0)
+	        )
+	{
+		if (tok->st_pos == json_inf_str_len)
+		{
+			current = json_object_new_double(is_negative ? -INFINITY : INFINITY); 
+			saved_state = json_tokener_state_finish;
+			state = json_tokener_state_eatws;
+			goto redo_char;
+		}
+	} else {
+		tok->err = json_tokener_error_parse_unexpected;
+		goto out;
+	}
+	tok->st_pos++;
+      }
+      break;
+    case json_tokener_state_null: /* aka starts with 'n' */
+      {
+	int size;
+	int size_nan;
+	printbuf_memappend_fast(tok->pb, &c, 1);
+	size = json_min(tok->st_pos+1, json_null_str_len);
+	size_nan = json_min(tok->st_pos+1, json_nan_str_len);
+	if((!(tok->flags & JSON_TOKENER_STRICT) &&
+	  strncasecmp(json_null_str, tok->pb->buf, size) == 0)
+	  || (strncmp(json_null_str, tok->pb->buf, size) == 0)
+	  ) {
+	  if (tok->st_pos == json_null_str_len) {
+	    current = NULL;
+	    saved_state = json_tokener_state_finish;
+	    state = json_tokener_state_eatws;
+	    goto redo_char;
+	  }
+	}
+	else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+	          strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
+	         (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
+	        )
+	{
+		if (tok->st_pos == json_nan_str_len)
+		{
+			current = json_object_new_double(NAN);
+			saved_state = json_tokener_state_finish;
+			state = json_tokener_state_eatws;
+			goto redo_char;
+		}
+	} else {
+	  tok->err = json_tokener_error_parse_null;
+	  goto out;
+	}
+	tok->st_pos++;
+      }
+      break;
+
+    case json_tokener_state_comment_start:
+      if(c == '*') {
+	state = json_tokener_state_comment;
+      } else if(c == '/') {
+	state = json_tokener_state_comment_eol;
+      } else {
+	tok->err = json_tokener_error_parse_comment;
+	goto out;
+      }
+      printbuf_memappend_fast(tok->pb, &c, 1);
+      break;
+
+    case json_tokener_state_comment:
+              {
+          /* Advance until we change state */
+          const char *case_start = str;
+          while(c != '*') {
+            if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+              printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+              goto out;
+            }
+          }
+          printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
+          state = json_tokener_state_comment_end;
+        }
+            break;
+
+    case json_tokener_state_comment_eol:
+      {
+	/* Advance until we change state */
+	const char *case_start = str;
+	while(c != '\n') {
+	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    goto out;
+	  }
+	}
+	printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
+	state = json_tokener_state_eatws;
+      }
+      break;
+
+    case json_tokener_state_comment_end:
+      printbuf_memappend_fast(tok->pb, &c, 1);
+      if(c == '/') {
+	MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
+	state = json_tokener_state_eatws;
+      } else {
+	state = json_tokener_state_comment;
+      }
+      break;
+
+    case json_tokener_state_string:
+      {
+	/* Advance until we change state */
+	const char *case_start = str;
+	while(1) {
+	  if(c == tok->quote_char) {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
+	    saved_state = json_tokener_state_finish;
+	    state = json_tokener_state_eatws;
+	    break;
+	  } else if(c == '\\') {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    saved_state = json_tokener_state_string;
+	    state = json_tokener_state_string_escape;
+	    break;
+	  }
+	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    goto out;
+	  }
+	}
+      }
+      break;
+
+    case json_tokener_state_string_escape:
+      switch(c) {
+      case '"':
+      case '\\':
+      case '/':
+	printbuf_memappend_fast(tok->pb, &c, 1);
+	state = saved_state;
+	break;
+      case 'b':
+      case 'n':
+      case 'r':
+      case 't':
+      case 'f':
+	if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
+	else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
+	else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
+	else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
+	else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
+	state = saved_state;
+	break;
+      case 'u':
+	tok->ucs_char = 0;
+	tok->st_pos = 0;
+	state = json_tokener_state_escape_unicode;
+	break;
+      default:
+	tok->err = json_tokener_error_parse_string;
+	goto out;
+      }
+      break;
+
+    case json_tokener_state_escape_unicode:
+	{
+          unsigned int got_hi_surrogate = 0;
+
+	  /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
+	  while(1) {
+	    if(strchr(json_hex_chars, c)) {
+	      tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
+	      if(tok->st_pos == 4) {
+		unsigned char unescaped_utf[4];
+
+                if (got_hi_surrogate) {
+		  if (IS_LOW_SURROGATE(tok->ucs_char)) {
+                    /* Recalculate the ucs_char, then fall thru to process normally */
+                    tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
+                  } else {
+                    /* Hi surrogate was not followed by a low surrogate */
+                    /* Replace the hi and process the rest normally */
+		    printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+                  }
+                  got_hi_surrogate = 0;
+                }
+
+		if (tok->ucs_char < 0x80) {
+		  unescaped_utf[0] = tok->ucs_char;
+		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
+		} else if (tok->ucs_char < 0x800) {
+		  unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
+		  unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
+		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
+		} else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
+                  /* Got a high surrogate.  Remember it and look for the
+                   * the beginning of another sequence, which should be the
+                   * low surrogate.
+                   */
+                  got_hi_surrogate = tok->ucs_char;
+                  /* Not at end, and the next two chars should be "\u" */
+                  if ((tok->char_offset+1 != len) &&
+                      (tok->char_offset+2 != len) &&
+                      (str[1] == '\\') &&
+                      (str[2] == 'u'))
+                  {
+                /* Advance through the 16 bit surrogate, and move on to the
+                 * next sequence. The next step is to process the following
+                 * characters.
+                 */
+	            if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
+                    printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+                }
+                    /* Advance to the first char of the next sequence and
+                     * continue processing with the next sequence.
+                     */
+	            if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+	              printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+	              goto out;
+                    }
+	            tok->ucs_char = 0;
+                    tok->st_pos = 0;
+                    continue; /* other json_tokener_state_escape_unicode */
+                  } else {
+                    /* Got a high surrogate without another sequence following
+                     * it.  Put a replacement char in for the hi surrogate
+                     * and pretend we finished.
+                     */
+		    printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+                  }
+		} else if (IS_LOW_SURROGATE(tok->ucs_char)) {
+                  /* Got a low surrogate not preceded by a high */
+		  printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+                } else if (tok->ucs_char < 0x10000) {
+		  unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
+		  unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+		  unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
+		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
+		} else if (tok->ucs_char < 0x110000) {
+		  unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
+		  unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
+		  unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+		  unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
+		  printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
+		} else {
+                  /* Don't know what we got--insert the replacement char */
+		  printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+                }
+		state = saved_state;
+		break;
+	      }
+	    } else {
+	      tok->err = json_tokener_error_parse_string;
+	      goto out;
+	    }
+	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+            if (got_hi_surrogate) /* Clean up any pending chars */
+	      printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+	    goto out;
+	  }
+	}
+      }
+      break;
+
+    case json_tokener_state_boolean:
+      {
+	int size1, size2;
+	printbuf_memappend_fast(tok->pb, &c, 1);
+	size1 = json_min(tok->st_pos+1, json_true_str_len);
+	size2 = json_min(tok->st_pos+1, json_false_str_len);
+	if((!(tok->flags & JSON_TOKENER_STRICT) &&
+	  strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
+	  || (strncmp(json_true_str, tok->pb->buf, size1) == 0)
+	  ) {
+	  if(tok->st_pos == json_true_str_len) {
+	    current = json_object_new_boolean(1);
+	    saved_state = json_tokener_state_finish;
+	    state = json_tokener_state_eatws;
+	    goto redo_char;
+	  }
+	} else if((!(tok->flags & JSON_TOKENER_STRICT) &&
+	  strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
+	  || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
+	  if(tok->st_pos == json_false_str_len) {
+	    current = json_object_new_boolean(0);
+	    saved_state = json_tokener_state_finish;
+	    state = json_tokener_state_eatws;
+	    goto redo_char;
+	  }
+	} else {
+	  tok->err = json_tokener_error_parse_boolean;
+	  goto out;
+	}
+	tok->st_pos++;
+      }
+      break;
+
+    case json_tokener_state_number:
+      {
+	/* Advance until we change state */
+	const char *case_start = str;
+	int case_len=0;
+	while(c && strchr(json_number_chars, c)) {
+	  ++case_len;
+	  if(c == '.' || c == 'e' || c == 'E')
+	    tok->is_double = 1;
+	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+	    printbuf_memappend_fast(tok->pb, case_start, case_len);
+	    goto out;
+	  }
+	}
+        if (case_len>0)
+          printbuf_memappend_fast(tok->pb, case_start, case_len);
+
+	// Check for -Infinity
+	if (tok->pb->buf[0] == '-' && case_len == 1 &&
+	    (c == 'i' || c == 'I'))
+	{
+		state = json_tokener_state_inf;
+		goto redo_char;
+	}
+      }
+      {
+	int64_t num64;
+	double  numd;
+	if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
+		if (num64 && tok->pb->buf[0]=='0' && (tok->flags & JSON_TOKENER_STRICT)) {
+			/* in strict mode, number must not start with 0 */
+			tok->err = json_tokener_error_parse_number;
+			goto out;
+		}
+		current = json_object_new_int64(num64);
+	}
+	else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
+	{
+          current = json_object_new_double_s(numd, tok->pb->buf);
+        } else {
+          tok->err = json_tokener_error_parse_number;
+          goto out;
+        }
+        saved_state = json_tokener_state_finish;
+        state = json_tokener_state_eatws;
+        goto redo_char;
+      }
+      break;
+
+    case json_tokener_state_array_after_sep:
+    case json_tokener_state_array:
+      if(c == ']') {
+		if (state == json_tokener_state_array_after_sep &&
+			(tok->flags & JSON_TOKENER_STRICT))
+		{
+			tok->err = json_tokener_error_parse_unexpected;
+			goto out;
+		}
+	saved_state = json_tokener_state_finish;
+	state = json_tokener_state_eatws;
+      } else {
+	if(tok->depth >= tok->max_depth-1) {
+	  tok->err = json_tokener_error_depth;
+	  goto out;
+	}
+	state = json_tokener_state_array_add;
+	tok->depth++;
+	json_tokener_reset_level(tok, tok->depth);
+	goto redo_char;
+      }
+      break;
+
+    case json_tokener_state_array_add:
+      json_object_array_add(current, obj);
+      saved_state = json_tokener_state_array_sep;
+      state = json_tokener_state_eatws;
+      goto redo_char;
+
+    case json_tokener_state_array_sep:
+      if(c == ']') {
+	saved_state = json_tokener_state_finish;
+	state = json_tokener_state_eatws;
+      } else if(c == ',') {
+	saved_state = json_tokener_state_array_after_sep;
+	state = json_tokener_state_eatws;
+      } else {
+	tok->err = json_tokener_error_parse_array;
+	goto out;
+      }
+      break;
+
+    case json_tokener_state_object_field_start:
+    case json_tokener_state_object_field_start_after_sep:
+      if(c == '}') {
+		if (state == json_tokener_state_object_field_start_after_sep &&
+		    (tok->flags & JSON_TOKENER_STRICT))
+		{
+			tok->err = json_tokener_error_parse_unexpected;
+			goto out;
+		}
+	saved_state = json_tokener_state_finish;
+	state = json_tokener_state_eatws;
+      } else if (c == '"' || c == '\'') {
+	tok->quote_char = c;
+	printbuf_reset(tok->pb);
+	state = json_tokener_state_object_field;
+      } else {
+	tok->err = json_tokener_error_parse_object_key_name;
+	goto out;
+      }
+      break;
+
+    case json_tokener_state_object_field:
+      {
+	/* Advance until we change state */
+	const char *case_start = str;
+	while(1) {
+	  if(c == tok->quote_char) {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    obj_field_name = strdup(tok->pb->buf);
+	    saved_state = json_tokener_state_object_field_end;
+	    state = json_tokener_state_eatws;
+	    break;
+	  } else if(c == '\\') {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    saved_state = json_tokener_state_object_field;
+	    state = json_tokener_state_string_escape;
+	    break;
+	  }
+	  if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+	    printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+	    goto out;
+	  }
+	}
+      }
+      break;
+
+    case json_tokener_state_object_field_end:
+      if(c == ':') {
+	saved_state = json_tokener_state_object_value;
+	state = json_tokener_state_eatws;
+      } else {
+	tok->err = json_tokener_error_parse_object_key_sep;
+	goto out;
+      }
+      break;
+
+    case json_tokener_state_object_value:
+      if(tok->depth >= tok->max_depth-1) {
+	tok->err = json_tokener_error_depth;
+	goto out;
+      }
+      state = json_tokener_state_object_value_add;
+      tok->depth++;
+      json_tokener_reset_level(tok, tok->depth);
+      goto redo_char;
+
+    case json_tokener_state_object_value_add:
+      json_object_object_add(current, obj_field_name, obj);
+      free(obj_field_name);
+      obj_field_name = NULL;
+      saved_state = json_tokener_state_object_sep;
+      state = json_tokener_state_eatws;
+      goto redo_char;
+
+    case json_tokener_state_object_sep:
+      if(c == '}') {
+	saved_state = json_tokener_state_finish;
+	state = json_tokener_state_eatws;
+      } else if(c == ',') {
+	saved_state = json_tokener_state_object_field_start_after_sep;
+	state = json_tokener_state_eatws;
+      } else {
+	tok->err = json_tokener_error_parse_object_value_sep;
+	goto out;
+      }
+      break;
+
+    }
+    if (!ADVANCE_CHAR(str, tok))
+      goto out;
+  } /* while(POP_CHAR) */
+
+ out:
+  if (c &&
+     (state == json_tokener_state_finish) &&
+     (tok->depth == 0) &&
+     (tok->flags & JSON_TOKENER_STRICT)) {
+      /* unexpected char after JSON data */
+      tok->err = json_tokener_error_parse_unexpected;
+  }
+  if (!c) { /* We hit an eof char (0) */
+    if(state != json_tokener_state_finish &&
+       saved_state != json_tokener_state_finish)
+      tok->err = json_tokener_error_parse_eof;
+  }
+
+#ifdef HAVE_SETLOCALE
+  setlocale(LC_NUMERIC, oldlocale);
+  if (oldlocale) free(oldlocale);
+#endif
+
+  if (tok->err == json_tokener_success)
+  {
+    json_object *ret = json_object_get(current);
+	int ii;
+
+	/* Partially reset, so we parse additional objects on subsequent calls. */
+    for(ii = tok->depth; ii >= 0; ii--)
+      json_tokener_reset_level(tok, ii);
+    return ret;
+  }
+
+  MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
+	   json_tokener_errors[tok->err], tok->char_offset);
+  return NULL;
+}
+
+void json_tokener_set_flags(struct json_tokener *tok, int flags)
+{
+	tok->flags = flags;
+}
diff --git a/modules/kazoo/deps/json_tokener.h b/modules/kazoo/deps/json_tokener.h
new file mode 100644
index 0000000..a72d2bd
--- /dev/null
+++ b/modules/kazoo/deps/json_tokener.h
@@ -0,0 +1,208 @@
+/*
+ * $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_tokener_h_
+#define _json_tokener_h_
+
+#include <stddef.h>
+#include "json_object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum json_tokener_error {
+  json_tokener_success,
+  json_tokener_continue,
+  json_tokener_error_depth,
+  json_tokener_error_parse_eof,
+  json_tokener_error_parse_unexpected,
+  json_tokener_error_parse_null,
+  json_tokener_error_parse_boolean,
+  json_tokener_error_parse_number,
+  json_tokener_error_parse_array,
+  json_tokener_error_parse_object_key_name,
+  json_tokener_error_parse_object_key_sep,
+  json_tokener_error_parse_object_value_sep,
+  json_tokener_error_parse_string,
+  json_tokener_error_parse_comment,
+  json_tokener_error_size
+};
+
+enum json_tokener_state {
+  json_tokener_state_eatws,
+  json_tokener_state_start,
+  json_tokener_state_finish,
+  json_tokener_state_null,
+  json_tokener_state_comment_start,
+  json_tokener_state_comment,
+  json_tokener_state_comment_eol,
+  json_tokener_state_comment_end,
+  json_tokener_state_string,
+  json_tokener_state_string_escape,
+  json_tokener_state_escape_unicode,
+  json_tokener_state_boolean,
+  json_tokener_state_number,
+  json_tokener_state_array,
+  json_tokener_state_array_add,
+  json_tokener_state_array_sep,
+  json_tokener_state_object_field_start,
+  json_tokener_state_object_field,
+  json_tokener_state_object_field_end,
+  json_tokener_state_object_value,
+  json_tokener_state_object_value_add,
+  json_tokener_state_object_sep,
+  json_tokener_state_array_after_sep,
+  json_tokener_state_object_field_start_after_sep,
+  json_tokener_state_inf
+};
+
+struct json_tokener_srec
+{
+  enum json_tokener_state state, saved_state;
+  struct json_object *obj;
+  struct json_object *current;
+  char *obj_field_name;
+};
+
+#define JSON_TOKENER_DEFAULT_DEPTH 32
+
+struct json_tokener
+{
+  char *str;
+  struct printbuf *pb;
+  int max_depth, depth, is_double, st_pos, char_offset;
+  enum json_tokener_error err;
+  unsigned int ucs_char;
+  char quote_char;
+  struct json_tokener_srec *stack;
+  int flags;
+};
+
+/**
+ * Be strict when parsing JSON input.  Use caution with
+ * this flag as what is considered valid may become more
+ * restrictive from one release to the next, causing your
+ * code to fail on previously working input.
+ *
+ * This flag is not set by default.
+ *
+ * @see json_tokener_set_flags()
+ */
+#define JSON_TOKENER_STRICT  0x01
+
+/**
+ * Given an error previously returned by json_tokener_get_error(),
+ * return a human readable description of the error.
+ *
+ * @return a generic error message is returned if an invalid error value is provided.
+ */
+const char *json_tokener_error_desc(enum json_tokener_error jerr);
+
+/**
+ * Retrieve the error caused by the last call to json_tokener_parse_ex(),
+ * or json_tokener_success if there is no error.
+ *
+ * When parsing a JSON string in pieces, if the tokener is in the middle
+ * of parsing this will return json_tokener_continue.
+ *
+ * See also json_tokener_error_desc().
+ */
+enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
+
+extern struct json_tokener* json_tokener_new(void);
+extern struct json_tokener* json_tokener_new_ex(int depth);
+extern void json_tokener_free(struct json_tokener *tok);
+extern void json_tokener_reset(struct json_tokener *tok);
+extern struct json_object* json_tokener_parse(const char *str);
+extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
+
+/**
+ * Set flags that control how parsing will be done.
+ */
+extern void json_tokener_set_flags(struct json_tokener *tok, int flags);
+
+/** 
+ * Parse a string and return a non-NULL json_object if a valid JSON value
+ * is found.  The string does not need to be a JSON object or array;
+ * it can also be a string, number or boolean value.
+ *
+ * A partial JSON string can be parsed.  If the parsing is incomplete,
+ * NULL will be returned and json_tokener_get_error() will be return 
+ * json_tokener_continue.
+ * json_tokener_parse_ex() can then be called with additional bytes in str
+ * to continue the parsing.  
+ *
+ * If json_tokener_parse_ex() returns NULL and the error anything other than
+ * json_tokener_continue, a fatal error has occurred and parsing must be
+ * halted.  Then tok object must not be re-used until json_tokener_reset() is
+ * called.
+ *
+ * When a valid JSON value is parsed, a non-NULL json_object will be
+ * returned.  Also, json_tokener_get_error() will return json_tokener_success.
+ * Be sure to check the type with json_object_is_type() or
+ * json_object_get_type() before using the object.
+ *
+ * @b XXX this shouldn't use internal fields:
+ * Trailing characters after the parsed value do not automatically cause an 
+ * error.  It is up to the caller to decide whether to treat this as an
+ * error or to handle the additional characters, perhaps by parsing another
+ * json value starting from that point.
+ *
+ * Extra characters can be detected by comparing the tok->char_offset against
+ * the length of the last len parameter passed in.
+ *
+ * The tokener does \b not maintain an internal buffer so the caller is
+ * responsible for calling json_tokener_parse_ex with an appropriate str
+ * parameter starting with the extra characters.
+ *
+ * This interface is presently not 64-bit clean due to the int len argument
+ * so the function limits the maximum string size to INT32_MAX (2GB).
+ * If the function is called with len == -1 then strlen is called to check
+ * the string length is less than INT32_MAX (2GB)
+ *
+ * Example:
+ * @code
+json_object *jobj = NULL;
+const char *mystring = NULL;
+int stringlen = 0;
+enum json_tokener_error jerr;
+do {
+	mystring = ...  // get JSON string, e.g. read from file, etc...
+	stringlen = strlen(mystring);
+	jobj = json_tokener_parse_ex(tok, mystring, stringlen);
+} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+if (jerr != json_tokener_success)
+{
+	fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+	// Handle errors, as appropriate for your application.
+}
+if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
+{
+	// Handle extra characters after parsed object as desired.
+	// e.g. issue an error, parse another object from that point, etc...
+}
+// Success, use jobj here.
+
+@endcode
+ *
+ * @param tok a json_tokener previously allocated with json_tokener_new()
+ * @param str an string with any valid JSON expression, or portion of.  This does not need to be null terminated.
+ * @param len the length of str
+ */
+extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
+						 const char *str, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/json_util.c b/modules/kazoo/deps/json_util.c
new file mode 100644
index 0000000..531f9af
--- /dev/null
+++ b/modules/kazoo/deps/json_util.c
@@ -0,0 +1,300 @@
+/*
+ * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+#undef realloc
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifdef WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <io.h>
+#endif /* defined(WIN32) */
+
+#if !defined(HAVE_OPEN) && defined(WIN32)
+# define open _open
+#endif
+
+#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
+  /* MSC has the version as _snprintf */
+# define snprintf _snprintf
+#elif !defined(HAVE_SNPRINTF)
+# error You do not have snprintf on your system.
+#endif /* HAVE_SNPRINTF */
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_util.h"
+
+static int sscanf_is_broken = 0;
+static int sscanf_is_broken_testdone = 0;
+static void sscanf_is_broken_test(void);
+
+struct json_object* json_object_from_file(const char *filename)
+{
+  struct printbuf *pb;
+  struct json_object *obj;
+  char buf[JSON_FILE_BUF_SIZE];
+  int fd, ret;
+
+  if((fd = open(filename, O_RDONLY)) < 0) {
+    MC_ERROR("json_object_from_file: error opening file %s: %s\n",
+	     filename, strerror(errno));
+    return NULL;
+  }
+  if(!(pb = printbuf_new())) {
+    close(fd);
+    MC_ERROR("json_object_from_file: printbuf_new failed\n");
+    return NULL;
+  }
+  while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
+    printbuf_memappend(pb, buf, ret);
+  }
+  close(fd);
+  if(ret < 0) {
+    MC_ERROR("json_object_from_file: error reading file %s: %s\n",
+	     filename, strerror(errno));
+    printbuf_free(pb);
+    return NULL;
+  }
+  obj = json_tokener_parse(pb->buf);
+  printbuf_free(pb);
+  return obj;
+}
+
+/* extended "format and write to file" function */
+
+int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags)
+{
+  const char *json_str;
+  int fd, ret;
+  unsigned int wpos, wsize;
+
+  if(!obj) {
+    MC_ERROR("json_object_to_file: object is null\n");
+    return -1;
+  }
+
+  if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
+    MC_ERROR("json_object_to_file: error opening file %s: %s\n",
+	     filename, strerror(errno));
+    return -1;
+  }
+
+  if(!(json_str = json_object_to_json_string_ext(obj,flags))) {
+    close(fd);
+    return -1;
+  }
+
+  wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
+  wpos = 0;
+  while(wpos < wsize) {
+    if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
+      close(fd);
+      MC_ERROR("json_object_to_file: error writing file %s: %s\n",
+	     filename, strerror(errno));
+      return -1;
+    }
+
+	/* because of the above check for ret < 0, we can safely cast and add */
+    wpos += (unsigned int)ret;
+  }
+
+  close(fd);
+  return 0;
+}
+
+// backwards compatible "format and write to file" function
+
+int json_object_to_file(const char *filename, struct json_object *obj)
+{
+  return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
+}
+
+int json_parse_double(const char *buf, double *retval)
+{
+  return (sscanf(buf, "%lf", retval)==1 ? 0 : 1);
+}
+
+/*
+ * Not all implementations of sscanf actually work properly.
+ * Check whether the one we're currently using does, and if
+ * it's broken, enable the workaround code.
+ */
+static void sscanf_is_broken_test()
+{
+	int64_t num64;
+	int ret_errno, is_int64_min, ret_errno2, is_int64_max;
+
+	(void)sscanf(" -01234567890123456789012345", "%" SCNd64, &num64);
+	ret_errno = errno;
+	is_int64_min = (num64 == INT64_MIN);
+
+	(void)sscanf(" 01234567890123456789012345", "%" SCNd64, &num64);
+	ret_errno2 = errno;
+	is_int64_max = (num64 == INT64_MAX);
+
+	if (ret_errno != ERANGE || !is_int64_min ||
+	    ret_errno2 != ERANGE || !is_int64_max)
+	{
+		MC_DEBUG("sscanf_is_broken_test failed, enabling workaround code\n");
+		sscanf_is_broken = 1;
+	}
+}
+
+int json_parse_int64(const char *buf, int64_t *retval)
+{
+	int64_t num64;
+	const char *buf_sig_digits;
+	int orig_has_neg;
+	int saved_errno;
+
+	if (!sscanf_is_broken_testdone)
+	{
+		sscanf_is_broken_test();
+		sscanf_is_broken_testdone = 1;
+	}
+
+	// Skip leading spaces
+	while (isspace((int)*buf) && *buf)
+		buf++;
+
+	errno = 0; // sscanf won't always set errno, so initialize
+	if (sscanf(buf, "%" SCNd64, &num64) != 1)
+	{
+		MC_DEBUG("Failed to parse, sscanf != 1\n");
+		return 1;
+	}
+
+	saved_errno = errno;
+	buf_sig_digits = buf;
+	orig_has_neg = 0;
+	if (*buf_sig_digits == '-')
+	{
+		buf_sig_digits++;
+		orig_has_neg = 1;
+	}
+
+	// Not all sscanf implementations actually work
+	if (sscanf_is_broken && saved_errno != ERANGE)
+	{
+		char buf_cmp[100];
+		char *buf_cmp_start = buf_cmp;
+		int recheck_has_neg = 0;
+		int buf_cmp_len;
+
+		// Skip leading zeros, but keep at least one digit
+		while (buf_sig_digits[0] == '0' && buf_sig_digits[1] != '\0')
+			buf_sig_digits++;
+		if (num64 == 0) // assume all sscanf impl's will parse -0 to 0
+			orig_has_neg = 0; // "-0" is the same as just plain "0"
+
+		snprintf(buf_cmp_start, sizeof(buf_cmp), "%" PRId64, num64);
+		if (*buf_cmp_start == '-')
+		{
+			recheck_has_neg = 1;
+			buf_cmp_start++;
+		}
+		// No need to skip leading spaces or zeros here.
+
+		buf_cmp_len = strlen(buf_cmp_start);
+		/**
+		 * If the sign is different, or
+		 * some of the digits are different, or
+		 * there is another digit present in the original string
+		 * then we have NOT successfully parsed the value.
+		 */
+		if (orig_has_neg != recheck_has_neg ||
+		    strncmp(buf_sig_digits, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
+			((int)strlen(buf_sig_digits) != buf_cmp_len &&
+			 isdigit((int)buf_sig_digits[buf_cmp_len])
+		    )
+		   )
+		{
+			saved_errno = ERANGE;
+		}
+	}
+
+	// Not all sscanf impl's set the value properly when out of range.
+	// Always do this, even for properly functioning implementations,
+	// since it shouldn't slow things down much.
+	if (saved_errno == ERANGE)
+	{
+		if (orig_has_neg)
+			num64 = INT64_MIN;
+		else
+			num64 = INT64_MAX;
+	}
+	*retval = num64;
+	return 0;
+}
+
+#ifndef HAVE_REALLOC
+void* rpl_realloc(void* p, size_t n)
+{
+	if (n == 0)
+		n = 1;
+	if (p == 0)
+		return malloc(n);
+	return realloc(p, n);
+}
+#endif
+
+#define NELEM(a)        (sizeof(a) / sizeof(a[0]))
+static const char* json_type_name[] = {
+  /* If you change this, be sure to update the enum json_type definition too */
+  "null",
+  "boolean",
+  "double",
+  "int",
+  "object",
+  "array",
+  "string",
+};
+
+const char *json_type_to_name(enum json_type o_type)
+{
+	int o_type_int = (int)o_type;
+	if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
+	{
+		MC_ERROR("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
+		return NULL;
+	}
+	return json_type_name[o_type];
+}
+
diff --git a/modules/kazoo/deps/json_util.h b/modules/kazoo/deps/json_util.h
new file mode 100644
index 0000000..1005e58
--- /dev/null
+++ b/modules/kazoo/deps/json_util.h
@@ -0,0 +1,41 @@
+/*
+ * $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_util_h_
+#define _json_util_h_
+
+#include "json_object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define JSON_FILE_BUF_SIZE 4096
+
+/* utility functions */
+extern struct json_object* json_object_from_file(const char *filename);
+extern int json_object_to_file(const char *filename, struct json_object *obj);
+extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags);
+extern int json_parse_int64(const char *buf, int64_t *retval);
+extern int json_parse_double(const char *buf, double *retval);
+
+
+/**
+ * Return a string describing the type of the object.
+ * e.g. "int", or "object", etc...
+ */
+extern const char *json_type_to_name(enum json_type o_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/libjson.c b/modules/kazoo/deps/libjson.c
new file mode 100644
index 0000000..5284fd0
--- /dev/null
+++ b/modules/kazoo/deps/libjson.c
@@ -0,0 +1,26 @@
+
+/* dummy source file for compatibility purposes */
+
+#if defined(HAVE_CDEFS_H)
+#include <sys/cdefs.h>
+#endif
+
+#ifndef __warn_references
+
+#if defined(__GNUC__)  && defined (HAS_GNU_WARNING_LONG)
+
+#define __warn_references(sym,msg)                  \
+  __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text");
+
+#else
+#define __warn_references(sym,msg)    /* nothing */
+#endif
+
+#endif 
+
+#include "json_object.h"
+
+__warn_references(json_object_get, "Warning: please link against libjson-c instead of libjson");
+
+/*        __asm__(".section .gnu.warning." __STRING(sym)  \
+            " ; .ascii \"" msg "\" ; .text") */
diff --git a/modules/kazoo/deps/linkhash.c b/modules/kazoo/deps/linkhash.c
new file mode 100644
index 0000000..712c387
--- /dev/null
+++ b/modules/kazoo/deps/linkhash.c
@@ -0,0 +1,602 @@
+/*
+ * $Id: linkhash.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <limits.h>
+
+#ifdef HAVE_ENDIAN_H
+# include <endian.h>    /* attempt to define endianness */
+#endif
+
+#include "random_seed.h"
+#include "linkhash.h"
+
+void lh_abort(const char *msg, ...)
+{
+	va_list ap;
+	va_start(ap, msg);
+	vprintf(msg, ap);
+	va_end(ap);
+	exit(1);
+}
+
+unsigned long lh_ptr_hash(const void *k)
+{
+	/* CAW: refactored to be 64bit nice */
+	return (unsigned long)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX);
+}
+
+int lh_ptr_equal(const void *k1, const void *k2)
+{
+	return (k1 == k2);
+}
+
+/* 
+ * hashlittle from lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+ * http://burtleburtle.net/bob/c/lookup3.c
+ * minor modifications to make functions static so no symbols are exported
+ * minor mofifications to compile with -Werror
+ */
+
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() 
+are externally useful functions.  Routines to test the hash are included 
+if SELF_TEST is defined.  You can use this free for any purpose.  It's in
+the public domain.  It has no warranty.
+
+You probably want to use hashlittle().  hashlittle() and hashbig()
+hash byte arrays.  hashlittle() is is faster than hashbig() on
+little-endian machines.  Intel and AMD are little-endian machines.
+On second thought, you probably want hashlittle2(), which is identical to
+hashlittle() except it returns two 32-bit hashes for the price of one.  
+You could implement hashbig2() if you wanted but I haven't bothered here.
+
+If you want to find a hash of, say, exactly 7 integers, do
+  a = i1;  b = i2;  c = i3;
+  mix(a,b,c);
+  a += i4; b += i5; c += i6;
+  mix(a,b,c);
+  a += i7;
+  final(a,b,c);
+then use c as the hash value.  If you have a variable length array of
+4-byte integers to hash, use hashword().  If you have a byte array (like
+a character string), use hashlittle().  If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().  
+
+Why is this so big?  I read 12 bytes at a time into 3 4-byte integers, 
+then mix those integers.  This is fast (you can do a lot more thorough
+mixing with 12*3 instructions on 3 integers than you can with 3 instructions
+on 1 byte), but shoehorning those bytes into integers efficiently is messy.
+-------------------------------------------------------------------------------
+*/
+
+/*
+ * My best guess at if you are big-endian or little-endian.  This may
+ * need adjustment.
+ */
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+     __BYTE_ORDER == __LITTLE_ENDIAN) || \
+    (defined(i386) || defined(__i386__) || defined(__i486__) || \
+     defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+       __BYTE_ORDER == __BIG_ENDIAN) || \
+      (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+#else
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 0
+#endif
+
+#define hashsize(n) ((uint32_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+  of top bits of (a,b,c), or in any combination of bottom bits of
+  (a,b,c).
+* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
+  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+  is commonly produced by subtraction) look like a single 1-bit
+  difference.
+* the base values were pseudorandom, all zero but one bit set, or 
+  all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+    4  6  8 16 19  4
+    9 15  3 18 27 15
+   14  9  3  7 17  3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta.  I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose 
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche.  There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a.  The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism.  Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism.  I did what I could.  Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+  a -= c;  a ^= rot(c, 4);  c += b; \
+  b -= a;  b ^= rot(a, 6);  a += c; \
+  c -= b;  c ^= rot(b, 8);  b += a; \
+  a -= c;  a ^= rot(c,16);  c += b; \
+  b -= a;  b ^= rot(a,19);  a += c; \
+  c -= b;  c ^= rot(b, 4);  b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different.  This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+  of top bits of (a,b,c), or in any combination of bottom bits of
+  (a,b,c).
+* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
+  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+  is commonly produced by subtraction) look like a single 1-bit
+  difference.
+* the base values were pseudorandom, all zero but one bit set, or 
+  all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+  4  8 15 26 3 22 24
+ 10  8 15 26 3 22 24
+ 11  8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+  c ^= b; c -= rot(b,14); \
+  a ^= c; a -= rot(c,11); \
+  b ^= a; b -= rot(a,25); \
+  c ^= b; c -= rot(b,16); \
+  a ^= c; a -= rot(c,4);  \
+  b ^= a; b -= rot(a,14); \
+  c ^= b; c -= rot(b,24); \
+}
+
+
+/*
+-------------------------------------------------------------------------------
+hashlittle() -- hash a variable-length key into a 32-bit value
+  k       : the key (the unaligned variable-length array of bytes)
+  length  : the length of the key, counting by bytes
+  initval : can be any 4-byte value
+Returns a 32-bit value.  Every bit of the key affects every bit of
+the return value.  Two keys differing by one or two bits will have
+totally different hash values.
+
+The best hash table sizes are powers of 2.  There is no need to do
+mod a prime (mod is sooo slow!).  If you need less than 32 bits,
+use a bitmask.  For example, if you need only 10 bits, do
+  h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (uint8_t **)k, do it like this:
+  for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
+
+By Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this
+code any way you wish, private, educational, or commercial.  It's free.
+
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable.  Do NOT use for cryptographic purposes.
+-------------------------------------------------------------------------------
+*/
+
+static uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
+{
+  uint32_t a,b,c;                                          /* internal state */
+  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
+
+  u.ptr = key;
+  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    /* 
+     * "k[2]&0xffffff" actually reads beyond the end of the string, but
+     * then masks off the part it's not allowed to read.  Because the
+     * string is aligned, the masked-off tail is in the same word as the
+     * rest of the string.  Every machine with memory protection I've seen
+     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * still catch it and complain.  The masking trick does make the hash
+     * noticably faster for short strings (like English words).
+     */
+#ifndef VALGRIND
+
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+    case 5 : b+=k[1]&0xff; a+=k[0]; break;
+    case 4 : a+=k[0]; break;
+    case 3 : a+=k[0]&0xffffff; break;
+    case 2 : a+=k[0]&0xffff; break;
+    case 1 : a+=k[0]&0xff; break;
+    case 0 : return c;              /* zero length strings require no mixing */
+    }
+
+#else /* make valgrind happy */
+
+    const uint8_t  *k8 = (const uint8_t *)k;
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
+    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
+    case 9 : c+=k8[8];                   /* fall through */
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
+    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
+    case 5 : b+=k8[4];                   /* fall through */
+    case 4 : a+=k[0]; break;
+    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
+    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
+    case 1 : a+=k8[0]; break;
+    case 0 : return c;
+    }
+
+#endif /* !valgrind */
+
+  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
+    const uint8_t  *k8;
+
+    /*--------------- all but last block: aligned reads and different mixing */
+    while (length > 12)
+    {
+      a += k[0] + (((uint32_t)k[1])<<16);
+      b += k[2] + (((uint32_t)k[3])<<16);
+      c += k[4] + (((uint32_t)k[5])<<16);
+      mix(a,b,c);
+      length -= 12;
+      k += 6;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    k8 = (const uint8_t *)k;
+    switch(length)
+    {
+    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
+    case 10: c+=k[4];
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 9 : c+=k8[8];                      /* fall through */
+    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
+    case 6 : b+=k[2];
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 5 : b+=k8[4];                      /* fall through */
+    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
+    case 2 : a+=k[0];
+             break;
+    case 1 : a+=k8[0];
+             break;
+    case 0 : return c;                     /* zero length requires no mixing */
+    }
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8_t *k = (const uint8_t *)key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      a += ((uint32_t)k[1])<<8;
+      a += ((uint32_t)k[2])<<16;
+      a += ((uint32_t)k[3])<<24;
+      b += k[4];
+      b += ((uint32_t)k[5])<<8;
+      b += ((uint32_t)k[6])<<16;
+      b += ((uint32_t)k[7])<<24;
+      c += k[8];
+      c += ((uint32_t)k[9])<<8;
+      c += ((uint32_t)k[10])<<16;
+      c += ((uint32_t)k[11])<<24;
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=((uint32_t)k[11])<<24;
+    case 11: c+=((uint32_t)k[10])<<16;
+    case 10: c+=((uint32_t)k[9])<<8;
+    case 9 : c+=k[8];
+    case 8 : b+=((uint32_t)k[7])<<24;
+    case 7 : b+=((uint32_t)k[6])<<16;
+    case 6 : b+=((uint32_t)k[5])<<8;
+    case 5 : b+=k[4];
+    case 4 : a+=((uint32_t)k[3])<<24;
+    case 3 : a+=((uint32_t)k[2])<<16;
+    case 2 : a+=((uint32_t)k[1])<<8;
+    case 1 : a+=k[0];
+             break;
+    case 0 : return c;
+    }
+  }
+
+  final(a,b,c);
+  return c;
+}
+
+unsigned long lh_char_hash(const void *k)
+{
+	static volatile int random_seed = -1;
+
+	if (random_seed == -1) {
+		int seed;
+		/* we can't use -1 as it is the unitialized sentinel */
+		while ((seed = json_c_get_random_seed()) == -1);
+#if defined __GNUC__
+		__sync_val_compare_and_swap(&random_seed, -1, seed);
+#elif defined _MSC_VER
+		InterlockedCompareExchange(&random_seed, seed, -1);
+#else
+#warning "racy random seed initializtion if used by multiple threads"
+		random_seed = seed; /* potentially racy */
+#endif
+	}
+
+	return hashlittle((const char*)k, strlen((const char*)k), random_seed); 
+}
+
+int lh_char_equal(const void *k1, const void *k2)
+{
+	return (strcmp((const char*)k1, (const char*)k2) == 0);
+}
+
+struct lh_table* lh_table_new(int size, const char *name,
+			      lh_entry_free_fn *free_fn,
+			      lh_hash_fn *hash_fn,
+			      lh_equal_fn *equal_fn)
+{
+	int i;
+	struct lh_table *t;
+
+	t = (struct lh_table*)calloc(1, sizeof(struct lh_table));
+	if(!t) lh_abort("lh_table_new: calloc failed\n");
+	t->count = 0;
+	t->size = size;
+	t->name = name;
+	t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry));
+	if(!t->table) lh_abort("lh_table_new: calloc failed\n");
+	t->free_fn = free_fn;
+	t->hash_fn = hash_fn;
+	t->equal_fn = equal_fn;
+	for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
+	return t;
+}
+
+struct lh_table* lh_kchar_table_new(int size, const char *name,
+				    lh_entry_free_fn *free_fn)
+{
+	return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal);
+}
+
+struct lh_table* lh_kptr_table_new(int size, const char *name,
+				   lh_entry_free_fn *free_fn)
+{
+	return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal);
+}
+
+void lh_table_resize(struct lh_table *t, int new_size)
+{
+	struct lh_table *new_t;
+	struct lh_entry *ent;
+
+	new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn);
+	ent = t->head;
+	while(ent) {
+		lh_table_insert(new_t, ent->k, ent->v);
+		ent = ent->next;
+	}
+	free(t->table);
+	t->table = new_t->table;
+	t->size = new_size;
+	t->head = new_t->head;
+	t->tail = new_t->tail;
+	t->resizes++;
+	free(new_t);
+}
+
+void lh_table_free(struct lh_table *t)
+{
+	struct lh_entry *c;
+	for(c = t->head; c != NULL; c = c->next) {
+		if(t->free_fn) {
+			t->free_fn(c);
+		}
+	}
+	free(t->table);
+	free(t);
+}
+
+
+int lh_table_insert(struct lh_table *t, void *k, const void *v)
+{
+	unsigned long h, n;
+
+	t->inserts++;
+	if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2);
+
+	h = t->hash_fn(k);
+	n = h % t->size;
+
+	while( 1 ) {
+		if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break;
+		t->collisions++;
+		if ((int)++n == t->size) n = 0;
+	}
+
+	t->table[n].k = k;
+	t->table[n].v = v;
+	t->count++;
+
+	if(t->head == NULL) {
+		t->head = t->tail = &t->table[n];
+		t->table[n].next = t->table[n].prev = NULL;
+	} else {
+		t->tail->next = &t->table[n];
+		t->table[n].prev = t->tail;
+		t->table[n].next = NULL;
+		t->tail = &t->table[n];
+	}
+
+	return 0;
+}
+
+
+struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
+{
+	unsigned long h = t->hash_fn(k);
+	unsigned long n = h % t->size;
+	int count = 0;
+
+	t->lookups++;
+	while( count < t->size ) {
+		if(t->table[n].k == LH_EMPTY) return NULL;
+		if(t->table[n].k != LH_FREED &&
+		   t->equal_fn(t->table[n].k, k)) return &t->table[n];
+		if ((int)++n == t->size) n = 0;
+		count++;
+	}
+	return NULL;
+}
+
+
+const void* lh_table_lookup(struct lh_table *t, const void *k)
+{
+	void *result;
+	lh_table_lookup_ex(t, k, &result);
+	return result;
+}
+
+json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v)
+{
+	struct lh_entry *e = lh_table_lookup_entry(t, k);
+	if (e != NULL) {
+		if (v != NULL) *v = (void *)e->v;
+		return TRUE; /* key found */
+	}
+	if (v != NULL) *v = NULL;
+	return FALSE; /* key not found */
+}
+
+int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
+{
+	ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
+
+	/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
+	if(n < 0) { return -2; }
+
+	if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1;
+	t->count--;
+	if(t->free_fn) t->free_fn(e);
+	t->table[n].v = NULL;
+	t->table[n].k = LH_FREED;
+	if(t->tail == &t->table[n] && t->head == &t->table[n]) {
+		t->head = t->tail = NULL;
+	} else if (t->head == &t->table[n]) {
+		t->head->next->prev = NULL;
+		t->head = t->head->next;
+	} else if (t->tail == &t->table[n]) {
+		t->tail->prev->next = NULL;
+		t->tail = t->tail->prev;
+	} else {
+		t->table[n].prev->next = t->table[n].next;
+		t->table[n].next->prev = t->table[n].prev;
+	}
+	t->table[n].next = t->table[n].prev = NULL;
+	return 0;
+}
+
+
+int lh_table_delete(struct lh_table *t, const void *k)
+{
+	struct lh_entry *e = lh_table_lookup_entry(t, k);
+	if(!e) return -1;
+	return lh_table_delete_entry(t, e);
+}
+
+int lh_table_length(struct lh_table *t)
+{
+	return t->count;
+}
diff --git a/modules/kazoo/deps/linkhash.h b/modules/kazoo/deps/linkhash.h
new file mode 100644
index 0000000..950d09f
--- /dev/null
+++ b/modules/kazoo/deps/linkhash.h
@@ -0,0 +1,292 @@
+/*
+ * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+ 
+#ifndef _linkhash_h_
+#define _linkhash_h_
+
+#include "json_object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * golden prime used in hash functions
+ */
+#define LH_PRIME 0x9e370001UL
+
+/**
+ * The fraction of filled hash buckets until an insert will cause the table
+ * to be resized.  
+ * This can range from just above 0 up to 1.0.
+ */
+#define LH_LOAD_FACTOR 0.66
+
+/**
+ * sentinel pointer value for empty slots
+ */
+#define LH_EMPTY (void*)-1
+
+/**
+ * sentinel pointer value for freed slots
+ */
+#define LH_FREED (void*)-2
+
+struct lh_entry;
+
+/**
+ * callback function prototypes
+ */
+typedef void (lh_entry_free_fn) (struct lh_entry *e);
+/**
+ * callback function prototypes
+ */
+typedef unsigned long (lh_hash_fn) (const void *k);
+/**
+ * callback function prototypes
+ */
+typedef int (lh_equal_fn) (const void *k1, const void *k2);
+
+/**
+ * An entry in the hash table
+ */
+struct lh_entry {
+	/**
+	 * The key.
+	 */
+	void *k;
+	/**
+	 * The value.
+	 */
+	const void *v;
+	/**
+	 * The next entry
+	 */
+	struct lh_entry *next;
+	/**
+	 * The previous entry.
+	 */
+	struct lh_entry *prev;
+};
+
+
+/**
+ * The hash table structure.
+ */
+struct lh_table {
+	/**
+	 * Size of our hash.
+	 */
+	int size;
+	/**
+	 * Numbers of entries.
+	 */
+	int count;
+
+	/**
+	 * Number of collisions.
+	 */
+	int collisions;
+
+	/**
+	 * Number of resizes.
+	 */
+	int resizes;
+
+	/**
+	 * Number of lookups.
+	 */
+	int lookups;
+
+	/**
+	 * Number of inserts.
+	 */
+	int inserts;
+
+	/**
+	 * Number of deletes.
+	 */
+	int deletes;
+
+	/**
+	 * Name of the hash table.
+	 */
+	const char *name;
+
+	/**
+	 * The first entry.
+	 */
+	struct lh_entry *head;
+
+	/**
+	 * The last entry.
+	 */
+	struct lh_entry *tail;
+
+	struct lh_entry *table;
+
+	/**
+	 * A pointer onto the function responsible for freeing an entry.
+	 */
+	lh_entry_free_fn *free_fn;
+	lh_hash_fn *hash_fn;
+	lh_equal_fn *equal_fn;
+};
+
+
+/**
+ * Pre-defined hash and equality functions
+ */
+extern unsigned long lh_ptr_hash(const void *k);
+extern int lh_ptr_equal(const void *k1, const void *k2);
+
+extern unsigned long lh_char_hash(const void *k);
+extern int lh_char_equal(const void *k1, const void *k2);
+
+
+/**
+ * Convenience list iterator.
+ */
+#define lh_foreach(table, entry) \
+for(entry = table->head; entry; entry = entry->next)
+
+/**
+ * lh_foreach_safe allows calling of deletion routine while iterating.
+ */
+#define lh_foreach_safe(table, entry, tmp) \
+for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
+
+
+
+/**
+ * Create a new linkhash table.
+ * @param size initial table size. The table is automatically resized
+ * although this incurs a performance penalty.
+ * @param name the table name.
+ * @param free_fn callback function used to free memory for entries
+ * when lh_table_free or lh_table_delete is called.
+ * If NULL is provided, then memory for keys and values
+ * must be freed by the caller.
+ * @param hash_fn  function used to hash keys. 2 standard ones are defined:
+ * lh_ptr_hash and lh_char_hash for hashing pointer values
+ * and C strings respectively.
+ * @param equal_fn comparison function to compare keys. 2 standard ones defined:
+ * lh_ptr_hash and lh_char_hash for comparing pointer values
+ * and C strings respectively.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_table_new(int size, const char *name,
+				     lh_entry_free_fn *free_fn,
+				     lh_hash_fn *hash_fn,
+				     lh_equal_fn *equal_fn);
+
+/**
+ * Convenience function to create a new linkhash
+ * table with char keys.
+ * @param size initial table size.
+ * @param name table name.
+ * @param free_fn callback function used to free memory for entries.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_kchar_table_new(int size, const char *name,
+					   lh_entry_free_fn *free_fn);
+
+
+/**
+ * Convenience function to create a new linkhash
+ * table with ptr keys.
+ * @param size initial table size.
+ * @param name table name.
+ * @param free_fn callback function used to free memory for entries.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_kptr_table_new(int size, const char *name,
+					  lh_entry_free_fn *free_fn);
+
+
+/**
+ * Free a linkhash table.
+ * If a callback free function is provided then it is called for all
+ * entries in the table.
+ * @param t table to free.
+ */
+extern void lh_table_free(struct lh_table *t);
+
+
+/**
+ * Insert a record into the table.
+ * @param t the table to insert into.
+ * @param k a pointer to the key to insert.
+ * @param v a pointer to the value to insert.
+ */
+extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
+
+
+/**
+ * Lookup a record into the table.
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @return a pointer to the record structure of the value or NULL if it does not exist.
+ */
+extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k);
+
+/**
+ * Lookup a record into the table
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @return a pointer to the found value or NULL if it does not exist.
+ * @deprecated Use lh_table_lookup_ex instead.
+ */
+THIS_FUNCTION_IS_DEPRECATED(extern const void* lh_table_lookup(struct lh_table *t, const void *k));
+
+/**
+ * Lookup a record in the table
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @param v a pointer to a where to store the found value (set to NULL if it doesn't exist).
+ * @return whether or not the key was found
+ */
+extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v);
+
+/**
+ * Delete a record from the table.
+ * If a callback free function is provided then it is called for the
+ * for the item being deleted.
+ * @param t the table to delete from.
+ * @param e a pointer to the entry to delete.
+ * @return 0 if the item was deleted.
+ * @return -1 if it was not found.
+ */
+extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
+
+
+/**
+ * Delete a record from the table.
+ * If a callback free function is provided then it is called for the
+ * for the item being deleted.
+ * @param t the table to delete from.
+ * @param k a pointer to the key to delete.
+ * @return 0 if the item was deleted.
+ * @return -1 if it was not found.
+ */
+extern int lh_table_delete(struct lh_table *t, const void *k);
+
+extern int lh_table_length(struct lh_table *t);
+
+void lh_abort(const char *msg, ...);
+void lh_table_resize(struct lh_table *t, int new_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/math_compat.h b/modules/kazoo/deps/math_compat.h
new file mode 100644
index 0000000..f40b8fa
--- /dev/null
+++ b/modules/kazoo/deps/math_compat.h
@@ -0,0 +1,28 @@
+#ifndef __math_compat_h
+#define __math_compat_h
+
+/* Define isnan and isinf on Windows/MSVC */
+
+#ifndef HAVE_DECL_ISNAN
+# ifdef HAVE_DECL__ISNAN
+#include <float.h>
+#define isnan(x) _isnan(x)
+# endif
+#endif
+
+#ifndef HAVE_DECL_ISINF
+# ifdef HAVE_DECL__FINITE
+#include <float.h>
+#define isinf(x) (!_finite(x))
+# endif
+#endif
+
+#ifndef HAVE_DECL_NAN
+#error This platform does not have nan()
+#endif
+
+#ifndef HAVE_DECL_INFINITY
+#error This platform does not have INFINITY
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/printbuf.c b/modules/kazoo/deps/printbuf.c
new file mode 100644
index 0000000..9d56522
--- /dev/null
+++ b/modules/kazoo/deps/printbuf.c
@@ -0,0 +1,192 @@
+/*
+ * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ *
+ * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
+ * The copyrights to the contents of this file are licensed under the MIT License
+ * (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_STDARG_H
+# include <stdarg.h>
+#else /* !HAVE_STDARG_H */
+# error Not enough var arg support!
+#endif /* HAVE_STDARG_H */
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+
+static int printbuf_extend(struct printbuf *p, int min_size);
+
+struct printbuf* printbuf_new(void)
+{
+  struct printbuf *p;
+
+  p = (struct printbuf*)calloc(1, sizeof(struct printbuf));
+  if(!p) return NULL;
+  p->size = 32;
+  p->bpos = 0;
+  if(!(p->buf = (char*)malloc(p->size))) {
+    free(p);
+    return NULL;
+  }
+  return p;
+}
+
+
+/**
+ * Extend the buffer p so it has a size of at least min_size.
+ *
+ * If the current size is large enough, nothing is changed.
+ *
+ * Note: this does not check the available space!  The caller
+ *  is responsible for performing those calculations.
+ */
+static int printbuf_extend(struct printbuf *p, int min_size)
+{
+	char *t;
+	int new_size;
+
+	if (p->size >= min_size)
+		return 0;
+
+	new_size = json_max(p->size * 2, min_size + 8);
+#ifdef PRINTBUF_DEBUG
+	MC_DEBUG("printbuf_memappend: realloc "
+	  "bpos=%d min_size=%d old_size=%d new_size=%d\n",
+	  p->bpos, min_size, p->size, new_size);
+#endif /* PRINTBUF_DEBUG */
+	if(!(t = (char*)realloc(p->buf, new_size)))
+		return -1;
+	p->size = new_size;
+	p->buf = t;
+	return 0;
+}
+
+int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+{
+  if (p->size <= p->bpos + size + 1) {
+    if (printbuf_extend(p, p->bpos + size + 1) < 0)
+      return -1;
+  }
+  memcpy(p->buf + p->bpos, buf, size);
+  p->bpos += size;
+  p->buf[p->bpos]= '\0';
+  return size;
+}
+
+int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
+{
+	int size_needed;
+
+	if (offset == -1)
+		offset = pb->bpos;
+	size_needed = offset + len;
+	if (pb->size < size_needed)
+	{
+		if (printbuf_extend(pb, size_needed) < 0)
+			return -1;
+	}
+
+	memset(pb->buf + offset, charvalue, len);
+	if (pb->bpos < size_needed)
+		pb->bpos = size_needed;
+
+	return 0;
+}
+
+#if !defined(HAVE_VSNPRINTF) && defined(_MSC_VER)
+# define vsnprintf _vsnprintf
+#elif !defined(HAVE_VSNPRINTF) /* !HAVE_VSNPRINTF */
+# error Need vsnprintf!
+#endif /* !HAVE_VSNPRINTF && defined(WIN32) */
+
+#if !defined(HAVE_VASPRINTF)
+/* CAW: compliant version of vasprintf */
+static int vasprintf(char **buf, const char *fmt, va_list ap)
+{
+#ifndef WIN32
+	static char _T_emptybuffer = '\0';
+#endif /* !defined(WIN32) */
+	int chars;
+	char *b;
+
+	if(!buf) { return -1; }
+
+#ifdef WIN32
+	chars = _vscprintf(fmt, ap)+1;
+#else /* !defined(WIN32) */
+	/* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
+	   our buffer like on some 64bit sun systems.... but hey, its time to move on */
+	chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
+	if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
+#endif /* defined(WIN32) */
+
+	b = (char*)malloc(sizeof(char)*chars);
+	if(!b) { return -1; }
+
+	if((chars = vsprintf(b, fmt, ap)) < 0)
+	{
+		free(b);
+	} else {
+		*buf = b;
+	}
+
+	return chars;
+}
+#endif /* !HAVE_VASPRINTF */
+
+int sprintbuf(struct printbuf *p, const char *msg, ...)
+{
+  va_list ap;
+  char *t;
+  int size;
+  char buf[128];
+
+  /* user stack buffer first */
+  va_start(ap, msg);
+  size = vsnprintf(buf, 128, msg, ap);
+  va_end(ap);
+  /* if string is greater than stack buffer, then use dynamic string
+     with vasprintf.  Note: some implementation of vsnprintf return -1
+     if output is truncated whereas some return the number of bytes that
+     would have been written - this code handles both cases. */
+  if(size == -1 || size > 127) {
+    va_start(ap, msg);
+    if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
+    va_end(ap);
+    printbuf_memappend(p, t, size);
+    free(t);
+    return size;
+  } else {
+    printbuf_memappend(p, buf, size);
+    return size;
+  }
+}
+
+void printbuf_reset(struct printbuf *p)
+{
+  p->buf[0] = '\0';
+  p->bpos = 0;
+}
+
+void printbuf_free(struct printbuf *p)
+{
+  if(p) {
+    free(p->buf);
+    free(p);
+  }
+}
diff --git a/modules/kazoo/deps/printbuf.h b/modules/kazoo/deps/printbuf.h
new file mode 100644
index 0000000..b1bde7f
--- /dev/null
+++ b/modules/kazoo/deps/printbuf.h
@@ -0,0 +1,77 @@
+/*
+ * $Id: printbuf.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ *
+ * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
+ * The copyrights to the contents of this file are licensed under the MIT License
+ * (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+#ifndef _printbuf_h_
+#define _printbuf_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct printbuf {
+  char *buf;
+  int bpos;
+  int size;
+};
+
+extern struct printbuf*
+printbuf_new(void);
+
+/* As an optimization, printbuf_memappend_fast is defined as a macro
+ * that handles copying data if the buffer is large enough; otherwise
+ * it invokes printbuf_memappend_real() which performs the heavy
+ * lifting of realloc()ing the buffer and copying data.
+ * Your code should not use printbuf_memappend directly--use
+ * printbuf_memappend_fast instead.
+ */
+extern int
+printbuf_memappend(struct printbuf *p, const char *buf, int size);
+
+#define printbuf_memappend_fast(p, bufptr, bufsize)          \
+do {                                                         \
+  if ((p->size - p->bpos) > bufsize) {                       \
+    memcpy(p->buf + p->bpos, (bufptr), bufsize);             \
+    p->bpos += bufsize;                                      \
+    p->buf[p->bpos]= '\0';                                   \
+  } else {  printbuf_memappend(p, (bufptr), bufsize); }      \
+} while (0)
+
+#define printbuf_length(p) ((p)->bpos)
+
+/**
+ * Set len bytes of the buffer to charvalue, starting at offset offset.
+ * Similar to calling memset(x, charvalue, len);
+ *
+ * The memory allocated for the buffer is extended as necessary.
+ *
+ * If offset is -1, this starts at the end of the current data in the buffer.
+ */
+extern int
+printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
+
+extern int
+sprintbuf(struct printbuf *p, const char *msg, ...);
+
+extern void
+printbuf_reset(struct printbuf *p);
+
+extern void
+printbuf_free(struct printbuf *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/random_seed.c b/modules/kazoo/deps/random_seed.c
new file mode 100644
index 0000000..3b520d4
--- /dev/null
+++ b/modules/kazoo/deps/random_seed.c
@@ -0,0 +1,237 @@
+/*
+ * random_seed.c
+ *
+ * Copyright (c) 2013 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include <stdio.h>
+#include "config.h"
+
+#define DEBUG_SEED(s)
+
+
+#if defined ENABLE_RDRAND
+
+/* cpuid */
+
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+#define HAS_X86_CPUID 1
+
+static void do_cpuid(int regs[], int h)
+{
+    __asm__ __volatile__(
+#if defined __x86_64__
+                         "pushq %%rbx;\n"
+#else
+                         "pushl %%ebx;\n"
+#endif
+                         "cpuid;\n"
+#if defined __x86_64__
+                         "popq %%rbx;\n"
+#else
+                         "popl %%ebx;\n"
+#endif
+                         : "=a"(regs[0]), [ebx] "=r"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
+                         : "a"(h));
+}
+
+#elif defined _MSC_VER
+
+#define HAS_X86_CPUID 1
+#define do_cpuid __cpuid
+
+#endif
+
+/* has_rdrand */
+
+#if HAS_X86_CPUID
+
+static int has_rdrand()
+{
+    // CPUID.01H:ECX.RDRAND[bit 30] == 1
+    int regs[4];
+    do_cpuid(regs, 1);
+    return (regs[2] & (1 << 30)) != 0;
+}
+
+#endif
+
+/* get_rdrand_seed - GCC x86 and X64 */
+
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+
+#define HAVE_RDRAND 1
+
+static int get_rdrand_seed()
+{
+    DEBUG_SEED("get_rdrand_seed");
+    int _eax;
+    // rdrand eax
+    __asm__ __volatile__("1: .byte 0x0F\n"
+                         "   .byte 0xC7\n"
+                         "   .byte 0xF0\n"
+                         "   jnc 1b;\n"
+                         : "=a" (_eax));
+    return _eax;
+}
+
+#endif
+
+#if defined _MSC_VER
+
+#if _MSC_VER >= 1700
+#define HAVE_RDRAND 1
+
+/* get_rdrand_seed - Visual Studio 2012 and above */
+
+static int get_rdrand_seed()
+{
+    DEBUG_SEED("get_rdrand_seed");
+    int r;
+    while (_rdrand32_step(&r) == 0);
+    return r;
+}
+
+#elif defined _M_IX86
+#define HAVE_RDRAND 1
+
+/* get_rdrand_seed - Visual Studio 2010 and below - x86 only */
+
+static int get_rdrand_seed()
+{
+	DEBUG_SEED("get_rdrand_seed");
+	int _eax;
+retry:
+	// rdrand eax
+	__asm _emit 0x0F __asm _emit 0xC7 __asm _emit 0xF0
+	__asm jnc retry
+	__asm mov _eax, eax
+	return _eax;
+}
+
+#endif
+#endif
+
+#endif /* defined ENABLE_RDRAND */
+
+
+/* has_dev_urandom */
+
+#if defined (__APPLE__) || defined(__unix__) || defined(__linux__)
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define HAVE_DEV_RANDOM 1
+
+static const char *dev_random_file = "/dev/urandom";
+
+static int has_dev_urandom()
+{
+    struct stat buf;
+    if (stat(dev_random_file, &buf)) {
+        return 0;
+    }
+    return ((buf.st_mode & S_IFCHR) != 0);
+}
+
+
+/* get_dev_random_seed */
+
+static int get_dev_random_seed()
+{
+    DEBUG_SEED("get_dev_random_seed");
+    
+    int fd = open(dev_random_file, O_RDONLY);
+    if (fd < 0) {
+        fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
+        exit(1);
+    }
+    
+    int r;
+    ssize_t nread = read(fd, &r, sizeof(r));
+    if (nread != sizeof(r)) {
+        fprintf(stderr, "error read %s: %s", dev_random_file, strerror(errno));
+        exit(1);
+    }
+    else if (nread != sizeof(r)) {
+        fprintf(stderr, "error short read %s", dev_random_file);
+        exit(1);
+    }
+    close(fd);
+    return r;
+}
+
+#endif
+
+
+/* get_cryptgenrandom_seed */
+
+#ifdef WIN32
+
+#define HAVE_CRYPTGENRANDOM 1
+
+#include <windows.h>
+#pragma comment(lib, "advapi32.lib")
+
+static int get_cryptgenrandom_seed()
+{
+    DEBUG_SEED("get_cryptgenrandom_seed");
+    
+    HCRYPTPROV hProvider = 0;
+    int r;
+    
+    if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+        fprintf(stderr, "error CryptAcquireContextW");
+        exit(1);
+    }
+    
+    if (!CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r)) {
+        fprintf(stderr, "error CryptGenRandom");
+        exit(1);
+    }
+    
+    CryptReleaseContext(hProvider, 0);
+    
+    return r;
+}
+
+#endif
+
+
+/* get_time_seed */
+
+#include <time.h>
+
+static int get_time_seed()
+{
+    DEBUG_SEED("get_time_seed");
+    
+    return (int)time(NULL) * 433494437;
+}
+
+
+/* json_c_get_random_seed */
+
+int json_c_get_random_seed()
+{
+#if HAVE_RDRAND
+    if (has_rdrand()) return get_rdrand_seed();
+#endif
+#if HAVE_DEV_RANDOM
+    if (has_dev_urandom()) return get_dev_random_seed();
+#endif
+#if HAVE_CRYPTGENRANDOM
+    return get_cryptgenrandom_seed();
+#endif
+    return get_time_seed();
+}
diff --git a/modules/kazoo/deps/random_seed.h b/modules/kazoo/deps/random_seed.h
new file mode 100644
index 0000000..7362d67
--- /dev/null
+++ b/modules/kazoo/deps/random_seed.h
@@ -0,0 +1,25 @@
+/*
+ * random_seed.h
+ *
+ * Copyright (c) 2013 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael@metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef seed_h
+#define seed_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int json_c_get_random_seed();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/kazoo/deps/threads.h b/modules/kazoo/deps/threads.h
new file mode 100644
index 0000000..c2d80a6
--- /dev/null
+++ b/modules/kazoo/deps/threads.h
@@ -0,0 +1,29 @@
+/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */
+/*
+ * Copyright 2012-2013 Michael Steinert
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef AMQP_THREADS_H
+#define AMQP_THREADS_H
+
+#include <pthread.h>
+
+#endif /* AMQP_THREADS_H */
diff --git a/modules/kazoo/kz_amqp.c b/modules/kazoo/kz_amqp.c
index ef90dfb..2d92471 100644
--- a/modules/kazoo/kz_amqp.c
+++ b/modules/kazoo/kz_amqp.c
@@ -1154,7 +1154,7 @@ int get_channel_index() {
 int kz_amqp_bind_targeted_channel(kz_amqp_conn_ptr kz_conn, int loopcount, int idx )
 {
     kz_amqp_bind_ptr bind = NULL;
-    amqp_queue_declare_ok_t *r = NULL;
+//    amqp_queue_declare_ok_t *r = NULL;
     str rpl_exch = str_init("targeted");
     str rpl_exch_type = str_init("direct");
     int ret = -1;
@@ -1182,13 +1182,13 @@ int kz_amqp_bind_targeted_channel(kz_amqp_conn_ptr kz_conn, int loopcount, int i
 		goto error;
     }
 
-    r = amqp_queue_declare(kz_conn->conn, channels[idx].channel, bind->queue, 0, 0, 1, 1, kz_amqp_empty_table);
+    amqp_queue_declare(kz_conn->conn, channels[idx].channel, bind->queue, 0, 0, 1, 1, kz_amqp_empty_table);
     if (kz_amqp_error("Declaring queue", amqp_get_rpc_reply(kz_conn->conn)))
     {
 		goto error;
     }
 
-	amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
+    amqp_exchange_declare(kz_conn->conn, channels[idx].channel, bind->exchange, bind->exchange_type, 0, 0, kz_amqp_empty_table);
     if (kz_amqp_error("Declaring exchange", amqp_get_rpc_reply(kz_conn->conn)))
     {
 		ret = -RET_AMQP_ERROR;
@@ -1547,7 +1547,7 @@ void kz_amqp_manager_loop(int child_no)
 	int INTERNAL_READ_COUNT , INTERNAL_READ_MAX_LOOP;
 	int CONSUMER_READ_COUNT , CONSUMER_READ_MAX_LOOP;
 	int ACK_READ_COUNT , ACK_READ_MAX_LOOP;
-	char* payload;
+//	char* payload;
 	int channel_res;
     kz_amqp_conn_ptr kzconn;
 	kz_amqp_cmd_ptr cmd;
@@ -1694,7 +1694,7 @@ void kz_amqp_manager_loop(int child_no)
 
     		CONSUMER_READ_COUNT = 0;
     	    while(CONSUME && (CONSUMER_READ_COUNT < CONSUMER_READ_MAX_LOOP || firstLoop)) {
-        		payload = NULL;
+//        		payload = NULL;
         		CONSUMER_READ_COUNT++;
 				amqp_envelope_t envelope;
 				amqp_maybe_release_buffers(kzconn->conn);
diff --git a/modules/kazoo/kz_pua.c b/modules/kazoo/kz_pua.c
index 562a060..b256e94 100644
--- a/modules/kazoo/kz_pua.c
+++ b/modules/kazoo/kz_pua.c
@@ -1,7 +1,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
-#include <json-c/json.h>
 #include "../../mem/mem.h"
 #include "../../timer_proc.h"
 #include "../../sr_module.h"
@@ -13,11 +12,11 @@
 #include "../pua/pua_bind.h"
 #include "../pua/send_publish.h"
 
-#include "kz_pua.h"
 #include "defs.h"
 #include "const.h"
 #include "kz_json.h"
 
+#include "kz_pua.h"
 
 extern int dbk_include_entity;
 extern int dbk_pua_mode;
-- 
1.7.10.4

