diff --git a/examples/messenger/c/CMakeLists.txt b/examples/messenger/c/CMakeLists.txt
index 4f40924..1b32d0c 100644
--- a/examples/messenger/c/CMakeLists.txt
+++ b/examples/messenger/c/CMakeLists.txt
@@ -21,8 +21,12 @@
 
 add_executable(recv recv.c)
 add_executable(send send.c)
+add_executable(recv-async recv-async.c)
+add_executable(send-async send-async.c)
 
 include_directories(${Proton_INCLUDE_DIRS})
 
 target_link_libraries(recv ${Proton_LIBRARIES})
 target_link_libraries(send ${Proton_LIBRARIES})
+target_link_libraries(recv-async ${Proton_LIBRARIES})
+target_link_libraries(send-async ${Proton_LIBRARIES})
diff --git a/examples/messenger/c/recv-async.c b/examples/messenger/c/recv-async.c
new file mode 100644
index 0000000..1f49166
--- /dev/null
+++ b/examples/messenger/c/recv-async.c
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// This is a re-implementation of recv.c using non-blocking/asynchronous calls.
+
+#include "proton/message.h"
+#include "proton/messenger.h"
+
+#include "pncompat/misc_funcs.inc"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+pn_message_t * message;
+pn_messenger_t * messenger;
+
+#define check(messenger)                                                     \
+  {                                                                          \
+    if(pn_messenger_errno(messenger))                                        \
+    {                                                                        \
+      die(__FILE__, __LINE__, pn_error_text(pn_messenger_error(messenger))); \
+    }                                                                        \
+  }                                                                          \
+
+void die(const char *file, int line, const char *message)
+{
+    fprintf(stderr, "%s:%i: %s\n", file, line, message);
+    exit(1);
+}
+
+void usage(void)
+{
+    printf("Usage: recv [options] <addr>\n");
+    printf("-c    \tPath to the certificate file.\n");
+    printf("-k    \tPath to the private key file.\n");
+    printf("-p    \tPassword for the private key.\n");
+    printf("<addr>\tAn address.\n");
+    exit(0);
+}
+
+void process(void) {
+    while(pn_messenger_incoming(messenger))
+    {
+        pn_messenger_get(messenger, message);
+        check(messenger);
+
+        {
+        pn_tracker_t tracker = pn_messenger_incoming_tracker(messenger);
+        char buffer[1024];
+        size_t buffsize = sizeof(buffer);
+        const char* subject = pn_message_get_subject(message);
+        pn_data_t* body = pn_message_body(message);
+        pn_data_format(body, buffer, &buffsize);
+
+        printf("Address: %s\n", pn_message_get_address(message));
+        printf("Subject: %s\n", subject ? subject : "(no subject)");
+        printf("Content: %s\n", buffer);
+
+        pn_messenger_accept(messenger, tracker, 0);
+        }
+    }
+}
+
+#if EMSCRIPTEN // For emscripten C/C++ to JavaScript compiler.
+void pump(int fd, void* userData) {
+    while (pn_messenger_work(messenger, 0) >= 0) {
+        process();
+    }
+}
+
+void onclose(int fd, void* userData) {
+    process();
+}
+
+void onerror(int fd, int errno, const char* msg, void* userData) {
+    printf("error callback fd = %d, errno = %d, msg = %s\n", fd, errno, msg);
+}
+#endif
+
+int main(int argc, char** argv)
+{
+    char* certificate = NULL;
+    char* privatekey = NULL;
+    char* password = NULL;
+    char* address = (char *) "amqp://~0.0.0.0";
+    int c;
+
+    message = pn_message();
+    messenger = pn_messenger(NULL);
+    pn_messenger_set_blocking(messenger, false); // Needs to be set non-blocking to behave asynchronously.
+
+    opterr = 0;
+
+    while((c = getopt(argc, argv, "hc:k:p:")) != -1)
+    {
+        switch(c)
+        {
+            case 'h':
+                usage();
+                break;
+
+            case 'c': certificate = optarg; break;
+            case 'k': privatekey = optarg; break;
+            case 'p': password = optarg; break;
+
+            case '?':
+                if (optopt == 'c' ||
+                    optopt == 'k' ||
+                    optopt == 'p')
+                {
+                    fprintf(stderr, "Option -%c requires an argument.\n", optopt);
+                }
+                else if(isprint(optopt))
+                {
+                    fprintf(stderr, "Unknown option `-%c'.\n", optopt);
+                }
+                else
+                {
+                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
+                }
+                return 1;
+            default:
+                abort();
+        }
+    }
+
+    if (optind < argc)
+    {
+        address = argv[optind];
+    }
+
+    /* load the various command line options if they're set */
+    if(certificate)
+    {
+        pn_messenger_set_certificate(messenger, certificate);
+    }
+
+    if(privatekey)
+    {
+        pn_messenger_set_private_key(messenger, privatekey);
+    }
+
+    if(password)
+    {
+        pn_messenger_set_password(messenger, password);
+    }
+
+    pn_messenger_start(messenger);
+    check(messenger);
+
+    pn_messenger_subscribe(messenger, address);
+    check(messenger);
+
+    pn_messenger_recv(messenger, -1); // Set to receive as many messages as messenger can buffer.
+
+#if EMSCRIPTEN // For emscripten C/C++ to JavaScript compiler.
+    emscripten_set_socket_error_callback(NULL, onerror);
+
+    emscripten_set_socket_open_callback(NULL, pump);
+    emscripten_set_socket_connection_callback(NULL, pump);
+    emscripten_set_socket_message_callback(NULL, pump);
+    emscripten_set_socket_close_callback(NULL, onclose);
+#else // For native compiler.
+    while (1) {
+        pn_messenger_work(messenger, -1); // Block indefinitely until there has been socket activity.
+        process();
+    }
+#endif
+
+    return 0;
+}
+
diff --git a/examples/messenger/c/send-async.c b/examples/messenger/c/send-async.c
new file mode 100644
index 0000000..2c76e6c
--- /dev/null
+++ b/examples/messenger/c/send-async.c
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// This is a re-implementation of send.c using non-blocking/asynchronous calls.
+
+#include "proton/message.h"
+#include "proton/messenger.h"
+#include "proton/driver.h"
+
+#include "pncompat/misc_funcs.inc"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+pn_message_t * message;
+pn_messenger_t * messenger;
+pn_tracker_t tracker;
+int running = 1;
+
+#define check(messenger)                                                     \
+  {                                                                          \
+    if(pn_messenger_errno(messenger))                                        \
+    {                                                                        \
+      die(__FILE__, __LINE__, pn_error_text(pn_messenger_error(messenger))); \
+    }                                                                        \
+  }                                                                          \
+
+void die(const char *file, int line, const char *message)
+{
+    fprintf(stderr, "%s:%i: %s\n", file, line, message);
+    exit(1);
+}
+
+void usage(void)
+{
+    printf("Usage: send [-a addr] [message]\n");
+    printf("-a     \tThe target address [amqp[s]://domain[/name]]\n");
+    printf("message\tA text string to send.\n");
+    exit(0);
+}
+
+void process(void) {
+    pn_status_t status = pn_messenger_status(messenger, tracker);
+    if (status != PN_STATUS_PENDING) {
+        if (running) {
+            pn_messenger_stop(messenger);
+            running = 0;
+        } 
+    }
+
+    if (pn_messenger_stopped(messenger)) {
+        pn_message_free(message);
+        pn_messenger_free(messenger);
+    }
+}
+
+#if EMSCRIPTEN // For emscripten C/C++ to JavaScript compiler.
+void pump(int fd, void* userData) {
+    while (pn_messenger_work(messenger, 0) >= 0) {
+        process();
+    }
+}
+
+void onclose(int fd, void* userData) {
+    process();
+}
+
+void onerror(int fd, int errno, const char* msg, void* userData) {
+    printf("error callback fd = %d, errno = %d, msg = %s\n", fd, errno, msg);
+}
+#endif
+
+int main(int argc, char** argv)
+{
+    int c;
+    opterr = 0;
+    char * address = (char *) "amqp://0.0.0.0";
+    char * msgtext = (char *) "Hello World!";
+
+    while((c = getopt(argc, argv, "ha:b:c:")) != -1)
+    {
+        switch(c)
+        {
+            case 'a': address = optarg; break;
+            case 'h': usage(); break;
+
+            case '?':
+                if(optopt == 'a')
+                {
+                    fprintf(stderr, "Option -%c requires an argument.\n", optopt);
+                }
+                else if(isprint(optopt))
+                {
+                    fprintf(stderr, "Unknown option `-%c'.\n", optopt);
+                }
+                else
+                {
+                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
+                }
+                return 1;
+            default:
+                abort();
+        }
+    }
+
+    if (optind < argc) msgtext = argv[optind];
+
+    message = pn_message();
+    messenger = pn_messenger(NULL);
+    pn_messenger_set_blocking(messenger, false); // Needs to be set non-blocking to behave asynchronously.
+    pn_messenger_set_outgoing_window(messenger, 1024); 
+
+    pn_messenger_start(messenger);
+
+    pn_message_set_address(message, address);
+    pn_data_t* body = pn_message_body(message);
+    pn_data_put_string(body, pn_bytes(strlen(msgtext), msgtext));
+
+    pn_messenger_put(messenger, message);
+    check(messenger);
+
+    tracker = pn_messenger_outgoing_tracker(messenger);
+
+#if EMSCRIPTEN // For emscripten C/C++ to JavaScript compiler.
+    emscripten_set_socket_error_callback(NULL, onerror);
+
+    emscripten_set_socket_open_callback(NULL, pump);
+    emscripten_set_socket_connection_callback(NULL, pump);
+    emscripten_set_socket_message_callback(NULL, pump);
+    emscripten_set_socket_close_callback(NULL, onclose);
+#else // For native compiler.
+    while (running) {
+        pn_messenger_work(messenger, -1); // Block indefinitely until there has been socket activity.
+        process();
+    }
+
+    while (!pn_messenger_stopped(messenger)) {
+        pn_messenger_work(messenger, 0);
+        process();
+    }
+#endif
+
+    return 0;
+}
+
diff --git a/examples/messenger/javascript/client.js b/examples/messenger/javascript/client.js
new file mode 100644
index 0000000..62f9a61
--- /dev/null
+++ b/examples/messenger/javascript/client.js
@@ -0,0 +1,104 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Simple client for use with server.js illustrating request/response
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proton = require("qpid-proton");
+
+    var address = "amqp://0.0.0.0";
+    var subject = "UK.WEATHER";
+    var replyTo = "~/replies";
+    var msgtext = "Hello World!";
+    var tracker = null;
+    var running = true;
+
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    var pumpData = function() {
+        while (messenger.incoming()) {
+            var t = messenger.get(message);
+
+            console.log("Reply");
+            console.log("Address: " + message.getAddress());
+            console.log("Subject: " + message.getSubject());
+
+            // body is the body as a native JavaScript Object, useful for most real cases.
+            //console.log("Content: " + message.body);
+
+            // data is the body as a proton.Data Object, used in this case because
+            // format() returns exactly the same representation as recv.c
+            console.log("Content: " + message.data.format());
+
+            messenger.accept(t);
+            messenger.stop();
+        }
+
+        if (messenger.isStopped()) {
+            message.free();
+            messenger.free();
+        }
+    };
+
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log("Usage: node client.js [-r replyTo] [-s subject] <addr> (default " + address + ")");
+            console.log("Options:");
+            console.log("  -r <reply to> The message replyTo (default " + replyTo + ")");
+            console.log("  -s <subject> The message subject (default " + subject + ")");
+            process.exit(0);
+        }
+
+        for (var i = 0; i < args.length; i++) {
+            var arg = args[i];
+            if (arg.charAt(0) === '-') {
+                i++;
+                var val = args[i];
+                if (arg === '-r') {
+                    replyTo = val;
+                } else if (arg === '-s') {
+                    subject = val;
+                }
+            } else {
+                address = arg;
+            }
+        }
+    }
+
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.setOutgoingWindow(1024);
+    messenger.recv(); // Receive as many messages as messenger can buffer.
+    messenger.start();
+
+    message.setAddress(address);
+    message.setSubject(subject);
+    message.setReplyTo(replyTo);
+    message.body = msgtext;
+
+    tracker = messenger.put(message);
+} else {
+    console.error("client.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/drain.js b/examples/messenger/javascript/drain.js
new file mode 100644
index 0000000..04ced73
--- /dev/null
+++ b/examples/messenger/javascript/drain.js
@@ -0,0 +1,70 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proton = require("qpid-proton");
+
+    console.log("drain not implemented yet");
+    process.exit(0);
+
+    var address = "amqp://~0.0.0.0";
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    var pumpData = function() {
+        while (messenger.incoming()) {
+            var t = messenger.get(message);
+
+            console.log("Address: " + message.getAddress());
+            console.log("Subject: " + message.getSubject());
+    
+            // body is the body as a native JavaScript Object, useful for most real cases.
+            //console.log("Content: " + message.body);
+
+            // data is the body as a proton.Data Object, used in this case because
+            // format() returns exactly the same representation as recv.c
+            console.log("Content: " + message.data.format());
+
+            messenger.accept(t);
+        }
+    };
+
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log("Usage: recv <addr> (default " + address + ").");
+            process.exit(0);
+        }
+
+        address = args[0];
+    }
+
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.recv(); // Receive as many messages as messenger can buffer.
+    messenger.start();
+
+    messenger.subscribe(address);
+} else {
+    console.error("drain.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/proxy.js b/examples/messenger/javascript/proxy.js
new file mode 100755
index 0000000..cac5cf5
--- /dev/null
+++ b/examples/messenger/javascript/proxy.js
@@ -0,0 +1,105 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * proxy.js is a simple node.js command line application that uses the ws2tcp.js
+ * library to proxy from a WebSocket to a TCP Socket or vice versa.
+ * <p>
+ * Usage: node proxy.js [options]
+ * Options:");
+ *  -p <listen port>, --port  <listen port> (default 5673 for ws2tcp
+ *                                                   5672 for tcp2ws)
+ *  -t <target port>, --tport <target port> (default listen port - 1 for ws2tcp
+ *                                                   listen port + 1 for tcp2ws)
+ *  -h <target host>, --thost <target host> (default 0.0.0.0)
+ *  -m <ws2tcp or tcp2ws>, --method <ws2tcp or tcp2ws> (default ws2tcp)
+ * @Author Fraser Adams
+ * @file
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proxy = require('./ws2tcp.js');
+
+    var lport = 5673;
+    var tport = lport - 1;
+    var thost = '0.0.0.0';
+    var method = 'ws2tcp';
+
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log("Usage: node proxy.js [options]");
+            console.log("Options:");
+            console.log("  -p <listen port>, --port  <listen port> (default " + lport + " for ws2tcp");
+            console.log("                                                   " + tport + " for tcp2ws)");
+            console.log("  -t <target port>, --tport <target port> (default listen port - 1 for ws2tcp");
+            console.log("                                                   listen port + 1 for tcp2ws)");
+            console.log("  -h <target host>, --thost <target host> (default " + thost + ")");
+            console.log("  -m <ws2tcp or tcp2ws>, --method <ws2tcp or tcp2ws> (default " + method + ")");
+            process.exit(0);
+        }
+
+        var lportSet = false;
+        var tportSet = false;
+        for (var i = 0; i < args.length; i++) {
+            var arg = args[i];
+            if (arg.charAt(0) === '-') {
+                i++;
+                var val = args[i];
+                if (arg === '-p' || arg === '--port') {
+                    lport = val;
+                    lportSet = true;
+                } else if (arg === '-t' || arg === '--tport') {
+                    tport = val;
+                    tportSet = true;
+                } else if (arg === '-h' || arg === '--thost') {
+                    thost = val;
+                } else if (arg === '-m' || arg === '--method') {
+                    method = val;
+                }
+            }
+        }
+
+        if (method === 'tcp2ws' && !lportSet) {
+            lport--;
+        }
+
+        if (!tportSet) {
+            tport = (method === 'ws2tcp') ? lport - 1 : +lport + 1;
+        }
+    }
+
+    if (method === 'tcp2ws') {
+        console.log("Proxying tcp -> ws");
+        console.log("Forwarding port " + lport + " to " + thost + ":" + tport);
+        proxy.tcp2ws(lport, thost, tport, 'AMQPWSB10');
+    } else if (method === 'ws2tcp') {
+        console.log("Proxying ws -> tcp");
+        console.log("Forwarding port " + lport + " to " + thost + ":" + tport);
+        proxy.ws2tcp(lport, thost, tport);
+    } else {
+        console.error("Method must be either ws2tcp or tcp2ws.");
+    }
+} else {
+    console.error("proxy.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/qpid-config.js b/examples/messenger/javascript/qpid-config.js
new file mode 100755
index 0000000..2f2a2ee
--- /dev/null
+++ b/examples/messenger/javascript/qpid-config.js
@@ -0,0 +1,1511 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * Port of qpid-config to JavaScript for Node.js, mainly intended as a demo to
+ * illustrate using QMF2 in JavaScript using the proton.Messenger JS binding.
+ * It illustrates a few things including how to use Messenger completely
+ * asynchronously including using an async request/response pattern with
+ * correlation IDs. It also proves interoperability of AMQP Map, List etc.
+ * between C++ and JavaScript as QMF2 is pretty much all about Lists of Maps.
+ * <p>
+ * The actual QMF2 code is pretty simple as we're just doing a basic getObjects
+ * it's made all the simpler because we can use JavaScript object literals as
+ * the JavaScript binding serialises and deserialises directly between JavaScript
+ * Objects and Lists and the AMQP type system so something that can be quite
+ * involved in languages like C++ and Java becomes quite simple in JavaScript,
+ * though the asynchronous nature of JavaScript provides its own opportunities
+ * for complication best illustrated by the need for the correlator object.
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+
+    var qmf = {}; // Create qmf namespace object.
+    qmf.Console = function() { // qmf.Console Constructor.
+        var proton = require("qpid-proton");
+        var message = new proton.Message();
+        var messenger = new proton.Messenger();
+
+        var brokerAddress = '';
+        var replyTo = '';
+
+        /**
+         * The correlator object is a mechanism used to correlate requests with
+         * their aynchronous responses. It might possible be better to make use
+         * of Promises to implement part of this behaviour but a mechanism would
+         * still be needed to correlate a request with its response callback in
+         * order to wrap things up in a Promise, so much of the behaviour of this
+         * object would still be required. In addition it seemed to make sense to
+         * make this QMF2 implementation fairly free of dependencies and using
+         * Promises would require external libraries. Instead the correlator
+         * implements "Promise-like" semantics, you might say a broken Promise :-)
+         * <p>
+         * in particular the request method behaves a *bit* like Promise.all()
+         * though it is mostly fake and takes an array of functions that call
+         * the add() method which is really the method used to associate response
+         * objects by correlationID. The then method is used to register a
+         * listener that will be called when all the requests that have been
+         * registered have received responses.
+         * TODO error/timeout handling.
+         */
+        var correlator = {
+            _resolve: null,
+            _objects: {},
+            add: function(id) {
+                this._objects[id] = {complete: false, list: null};
+            },
+            request: function() {
+                this._resolve = function() {console.log("Warning: No resolver has been set")};
+                return this;
+            },
+            then: function(resolver) {
+                this._resolve = resolver ? resolver : this._resolve;
+            },
+            resolve: function() {
+                var opcode = message.properties['qmf.opcode'];
+                var correlationID = message.getCorrelationID();
+                var resp = this._objects[correlationID];
+                if (opcode === '_query_response') {
+                    if (resp.list) {
+                        Array.prototype.push.apply(resp.list, message.body); // This is faster than concat.
+                    } else {
+                        resp.list = message.body;
+                    }
+        
+                    var partial = message.properties['partial'];
+                    if (!partial) {
+                        resp.complete = true;
+                    }
+        
+                    this._objects[correlationID] = resp;
+                    this._checkComplete();
+                } else if (opcode === '_method_response' || opcode === '_exception') {
+                    resp.list = message.body;
+                    resp.complete = true;
+                    this._objects[correlationID] = resp;
+                    this._checkComplete();
+                } else {
+                    console.error("Bad Message response, qmf.opcode = " + opcode);
+                }
+            },
+            _checkComplete: function() {
+                var response = {};
+                for (var id in this._objects) {
+                    var object = this._objects[id];
+                    if (object.complete) {
+                        response[id] = object.list;
+                    } else {
+                        return;
+                    }
+                }
+    
+                this._objects = {}; // Clear state ready for next call.
+                this._resolve(response.method ? response.method : response);
+            }
+        };  // End of correlator object definition.
+
+        var pumpData = function() {
+            while (messenger.incoming()) {
+                // The second parameter forces Binary payloads to be decoded as
+                // strings this is useful because the broker QMF Agent encodes
+                // strings as AMQP binary unfortunately.
+                var t = messenger.get(message, true);
+                correlator.resolve();
+                messenger.accept(t);
+            }
+    
+            if (messenger.isStopped()) {
+                message.free();
+                messenger.free();
+            }
+        };
+    
+        this.getObjects = function(packageName, className) {
+            message.setAddress(brokerAddress);
+            message.setSubject('broker');
+            message.setReplyTo(replyTo);
+            message.setCorrelationID(className);
+            message.properties = {
+                "routing-key": "broker", // Added for Java Broker
+                "x-amqp-0-10.app-id": "qmf2",
+                "method": "request",
+                "qmf.opcode": "_query_request",
+            };
+            message.body = {
+                "_what": "OBJECT",
+                "_schema_id": {
+                    "_package_name": packageName,
+                    "_class_name": className
+                }
+            };
+    
+            correlator.add(className);
+            messenger.put(message);
+        };
+
+        this.invokeMethod = function(object, method, arguments) {
+            var correlationID = 'method';
+            message.setAddress(brokerAddress);
+            message.setSubject('broker');
+            message.setReplyTo(replyTo);
+            message.setCorrelationID(correlationID);
+            message.properties = {
+                "routing-key": "broker", // Added for Java Broker
+                "x-amqp-0-10.app-id": "qmf2",
+                "method": "request",
+                "qmf.opcode": "_method_request",
+            };
+            message.body = {
+                "_object_id": object._object_id,
+                "_method_name" : method,
+                "_arguments"   : arguments
+            };
+    
+            correlator.add(correlationID);
+            messenger.put(message);
+        };
+
+        this.addConnection = function(addr, callback) {
+            brokerAddress = addr + '/qmf.default.direct';
+            var replyAddress = addr + '/#';
+    
+            messenger.on('subscription', function(subscription) {
+                var subscriptionAddress = subscription.getAddress();
+                var splitAddress = subscriptionAddress.split('/');
+                replyTo = splitAddress[splitAddress.length - 1];
+                callback();
+            });
+
+            messenger.subscribe(replyAddress);
+        }
+
+        this.destroy = function() {
+            messenger.stop(); 
+        }
+
+        this.request = function() {return correlator.request();}
+
+        messenger.on('error', function(error) {console.log(error);});
+        messenger.on('work', pumpData);
+        messenger.setOutgoingWindow(1024);
+        messenger.recv(); // Receive as many messages as messenger can buffer.
+        messenger.start();
+    }; // End of qmf.Console
+
+/************************* qpid-config business logic ************************/
+
+    var brokerAgent = new qmf.Console();
+
+    var _usage =
+    'Usage:  qpid-config [OPTIONS]\n' +
+    '        qpid-config [OPTIONS] exchanges [filter-string]\n' +
+    '        qpid-config [OPTIONS] queues    [filter-string]\n' +
+    '        qpid-config [OPTIONS] add exchange <type> <name> [AddExchangeOptions]\n' +
+    '        qpid-config [OPTIONS] del exchange <name>\n' +
+    '        qpid-config [OPTIONS] add queue <name> [AddQueueOptions]\n' +
+    '        qpid-config [OPTIONS] del queue <name> [DelQueueOptions]\n' +
+    '        qpid-config [OPTIONS] bind   <exchange-name> <queue-name> [binding-key]\n' +
+    '                  <for type xml>     [-f -|filename]\n' +
+    '                  <for type header>  [all|any] k1=v1 [, k2=v2...]\n' +
+    '        qpid-config [OPTIONS] unbind <exchange-name> <queue-name> [binding-key]\n' +
+    '        qpid-config [OPTIONS] reload-acl\n' +
+    '        qpid-config [OPTIONS] add <type> <name> [--argument <property-name>=<property-value>]\n' +
+    '        qpid-config [OPTIONS] del <type> <name>\n' +
+    '        qpid-config [OPTIONS] list <type> [--show-property <property-name>]\n';
+
+    var usage = function() {
+        console.log(_usage);
+        process.exit(-1);
+    };
+
+    var _description =
+    'Examples:\n' +
+    '\n' +
+    '$ qpid-config add queue q\n' +
+    '$ qpid-config add exchange direct d -a localhost:5672\n' +
+    '$ qpid-config exchanges -b 10.1.1.7:10000\n' +
+    '$ qpid-config queues -b guest/guest@broker-host:10000\n' +
+    '\n' +
+    'Add Exchange <type> values:\n' +
+    '\n' +
+    '    direct     Direct exchange for point-to-point communication\n' +
+    '    fanout     Fanout exchange for broadcast communication\n' +
+    '    topic      Topic exchange that routes messages using binding keys with wildcards\n' +
+    '    headers    Headers exchange that matches header fields against the binding keys\n' +
+    '    xml        XML Exchange - allows content filtering using an XQuery\n' +
+    '\n' +
+    '\n' +
+    'Queue Limit Actions:\n' +
+    '\n' +
+    '    none (default) - Use broker\'s default policy\n' +
+    '    reject         - Reject enqueued messages\n' +
+    '    ring           - Replace oldest unacquired message with new\n' +
+    '\n' +
+    'Replication levels:\n' +
+    '\n' +
+    '    none           - no replication\n' +
+    '    configuration  - replicate queue and exchange existence and bindings, but not messages.\n' +
+    '    all            - replicate configuration and messages\n';
+    
+    var _options =
+    'Options:\n' +
+    '  -h, --help            show this help message and exit\n' +
+    '\n' +
+    '  General Options:\n' +
+    '    -t <secs>, --timeout=<secs>\n' +
+    '                        Maximum time to wait for broker connection (in\n' +
+    '                        seconds)\n' +
+    '    -r, --recursive     Show bindings in queue or exchange list\n' +
+    '    -b <address>, --broker=<address>\n' +
+    '                        Address of qpidd broker with syntax:\n' +
+    '                        [username/password@] hostname | ip-address [:<port>]\n' +
+    '    -a <address>, --broker-addr=<address>\n' +
+    /* TODO Connection options
+    '    --sasl-mechanism=<mech>\n' +
+    '                        SASL mechanism for authentication (e.g. EXTERNAL,\n' +
+    '                        ANONYMOUS, PLAIN, CRAM-MD5, DIGEST-MD5, GSSAPI). SASL\n' +
+    '                        automatically picks the most secure available\n' +
+    '                        mechanism - use this option to override.\n' +
+    '    --ssl-certificate=<cert>\n' +
+    '                        Client SSL certificate (PEM Format)\n' +
+    '    --ssl-key=<key>     Client SSL private key (PEM Format)\n' +
+    '    --ha-admin          Allow connection to a HA backup broker.\n' +
+    */
+    '\n' +
+    '  Options for Listing Exchanges and Queues:\n' +
+    '    --ignore-default    Ignore the default exchange in exchange or queue list\n' +
+    '\n' +
+    '  Options for Adding Exchanges and Queues:\n' +
+    '    --alternate-exchange=<aexname>\n' +
+    '                        Name of the alternate-exchange for the new queue or\n' +
+    '                        exchange. Exchanges route messages to the alternate\n' +
+    '                        exchange if they are unable to route them elsewhere.\n' +
+    '                        Queues route messages to the alternate exchange if\n' +
+    '                        they are rejected by a subscriber or orphaned by queue\n' +
+    '                        deletion.\n' +
+    '    --durable           The new queue or exchange is durable.\n' +
+    '    --replicate=<level>\n' +
+    '                        Enable automatic replication in a HA cluster. <level>\n' +
+    '                        is \'none\', \'configuration\' or \'all\').\n' +
+    '\n' +
+    '  Options for Adding Queues:\n' +
+    '    --file-count=<n>    Number of files in queue\'s persistence journal\n' +
+    '    --file-size=<n>     File size in pages (64KiB/page)\n' +
+    '    --max-queue-size=<n>\n' +
+    '                        Maximum in-memory queue size as bytes\n' +
+    '    --max-queue-count=<n>\n' +
+    '                        Maximum in-memory queue size as a number of messages\n' +
+    '    --limit-policy=<policy>\n' +
+    '                        Action to take when queue limit is reached\n' +
+    '    --lvq-key=<key>     Last Value Queue key\n' +
+    '    --generate-queue-events=<n>\n' +
+    '                        If set to 1, every enqueue will generate an event that\n' +
+    '                        can be processed by registered listeners (e.g. for\n' +
+    '                        replication). If set to 2, events will be generated\n' +
+    '                        for enqueues and dequeues.\n' +
+    '    --flow-stop-size=<n>\n' +
+    '                        Turn on sender flow control when the number of queued\n' +
+    '                        bytes exceeds this value.\n' +
+    '    --flow-resume-size=<n>\n' +
+    '                        Turn off sender flow control when the number of queued\n' +
+    '                        bytes drops below this value.\n' +
+    '    --flow-stop-count=<n>\n' +
+    '                        Turn on sender flow control when the number of queued\n' +
+    '                        messages exceeds this value.\n' +
+    '    --flow-resume-count=<n>\n' +
+    '                        Turn off sender flow control when the number of queued\n' +
+    '                        messages drops below this value.\n' +
+    '    --group-header=<header-name>\n' +
+    '                        Enable message groups. Specify name of header that\n' +
+    '                        holds group identifier.\n' +
+    '    --shared-groups     Allow message group consumption across multiple\n' +
+    '                        consumers.\n' +
+    '    --argument=<NAME=VALUE>\n' +
+    '                        Specify a key-value pair to add to queue arguments\n' +
+    '    --start-replica=<broker-url>\n' +
+    '                        Start replication from the same-named queue at\n' +
+    '                        <broker-url>\n' +
+    '\n' +
+    '  Options for Adding Exchanges:\n' +
+    '    --sequence          Exchange will insert a \'qpid.msg_sequence\' field in\n' +
+    '                        the message header\n' +
+    '    --ive               Exchange will behave as an \'initial-value-exchange\',\n' +
+    '                        keeping a reference  to the last message forwarded and\n' +
+    '                        enqueuing that message to newly bound queues.\n' +
+    '\n' +
+    '  Options for Deleting Queues:\n' +
+    '    --force             Force delete of queue even if it\'s currently used or\n' +
+    '                        it\'s not empty\n' +
+    '    --force-if-not-empty\n' +
+    '                        Force delete of queue even if it\'s not empty\n' +
+    '    --force-if-used     Force delete of queue even if it\'s currently used\n' +
+    '\n' +
+    '  Options for Declaring Bindings:\n' +
+    '    -f <file.xq>, --file=<file.xq>\n' +
+    '                        For XML Exchange bindings - specifies the name of a\n' +
+    '                        file containing an XQuery.\n' +
+    '\n' +
+    '  Formatting options for \'list\' action:\n' +
+    '    --show-property=<property-name>\n' +
+    '                        Specify a property of an object to be included in\n' +
+    '                        output\n';
+    
+    var REPLICATE_LEVELS = {"none" : true, "configuration": true, "all": true};
+    var DEFAULT_PROPERTIES = {"exchange": {"name": true, "type": true, "durable": true},
+                                 "queue": {"name": true, "durable": true, "autoDelete": true}};
+    
+    var getValue = function(r) {
+        var value = null;
+        if (r.length === 2) {
+            value = r[1];
+            if (!isNaN(value)) {
+                value = parseInt(value);
+            }
+        }
+    
+        return value;
+    };
+    
+    var config = {
+        _recursive      : false,
+        _host           : 'guest:guest@localhost:5673', // Note 5673 not 5672 as we use WebSocket transport.
+        _connTimeout    : 10,
+        _ignoreDefault  : false,
+        _altern_ex      : null,
+        _durable        : false,
+        _replicate      : null,
+        _if_empty       : true,
+        _if_unused      : true,
+        _fileCount      : null,
+        _fileSize       : null,
+        _maxQueueSize   : null,
+        _maxQueueCount  : null,
+        _limitPolicy    : null,
+        _msgSequence    : false,
+        _lvq_key        : null,
+        _ive            : null,
+        _eventGeneration: null,
+        _file           : null,
+        _flowStopCount  : null,
+        _flowResumeCount: null,
+        _flowStopSize   : null,
+        _flowResumeSize : null,
+        _msgGroupHeader : null,
+        _sharedMsgGroup : false,
+        _extra_arguments: [],
+        _start_replica  : null,
+        _returnCode     : 0,
+        _list_properties: null,
+    
+        getOptions: function() {
+            var options = {};
+            for (var a = 0; a < this._extra_arguments.length; a++) {
+                var r = this._extra_arguments[a].split('=');
+                options[r[0]] = getValue(r);
+            }
+            return options;
+        }
+    };
+    
+    var FILECOUNT = 'qpid.file_count';
+    var FILESIZE  = 'qpid.file_size';
+    var MAX_QUEUE_SIZE  = 'qpid.max_size';
+    var MAX_QUEUE_COUNT  = 'qpid.max_count';
+    var POLICY_TYPE  = 'qpid.policy_type';
+    var LVQ_KEY = 'qpid.last_value_queue_key';
+    var MSG_SEQUENCE = 'qpid.msg_sequence';
+    var IVE = 'qpid.ive';
+    var QUEUE_EVENT_GENERATION = 'qpid.queue_event_generation';
+    var FLOW_STOP_COUNT   = 'qpid.flow_stop_count';
+    var FLOW_RESUME_COUNT = 'qpid.flow_resume_count';
+    var FLOW_STOP_SIZE    = 'qpid.flow_stop_size';
+    var FLOW_RESUME_SIZE  = 'qpid.flow_resume_size';
+    var MSG_GROUP_HDR_KEY = 'qpid.group_header_key';
+    var SHARED_MSG_GROUP  = 'qpid.shared_msg_group';
+    var REPLICATE = 'qpid.replicate';
+    
+    /**
+     * There are various arguments to declare that have specific program
+     * options in this utility. However there is now a generic mechanism for
+     * passing arguments as well. The SPECIAL_ARGS list contains the
+     * arguments for which there are specific program options defined
+     * i.e. the arguments for which there is special processing on add and
+     * list
+    */
+    var SPECIAL_ARGS={};
+    SPECIAL_ARGS[FILECOUNT] = true;
+    SPECIAL_ARGS[FILESIZE] = true;
+    SPECIAL_ARGS[MAX_QUEUE_SIZE] = true;
+    SPECIAL_ARGS[MAX_QUEUE_COUNT] = true;
+    SPECIAL_ARGS[POLICY_TYPE] = true;
+    SPECIAL_ARGS[LVQ_KEY] = true;
+    SPECIAL_ARGS[MSG_SEQUENCE] = true;
+    SPECIAL_ARGS[IVE] = true;
+    SPECIAL_ARGS[QUEUE_EVENT_GENERATION] = true;
+    SPECIAL_ARGS[FLOW_STOP_COUNT] = true;
+    SPECIAL_ARGS[FLOW_RESUME_COUNT] = true;
+    SPECIAL_ARGS[FLOW_STOP_SIZE] = true;
+    SPECIAL_ARGS[FLOW_RESUME_SIZE] = true;
+    SPECIAL_ARGS[MSG_GROUP_HDR_KEY] = true;
+    SPECIAL_ARGS[SHARED_MSG_GROUP] = true;
+    SPECIAL_ARGS[REPLICATE] = true;
+    
+    // Returns a String representation of an ObjectID.
+    var oid = function(id) {
+        return id._agent_epoch + ':' + id._object_name
+    };
+    
+    // Check if the supplied name contains the supplied filter String.
+    var filterMatch = function(name, filter) {
+        if (filter === '') {
+            return true;
+        }
+        if (name.indexOf(filter) === -1) {
+            return false;
+        }
+        return true;
+    };
+    
+    // Take the supplied List of QMF2 Objects and return a Map keyed by ObjectID.
+    var idMap = function(list) {
+        var map = {};
+        for (var i = 0; i < list.length; i++) {
+            var item = list[i];
+            map[oid(item._object_id)] = item;
+        }
+        return map;
+    };
+    
+    // Pretty-print the supplied Object.
+    var renderObject = function(obj, list) {
+        if (!obj) {
+            return '';
+        }
+        var string = '';
+        var addComma = false;
+        for (var prop in obj) {
+            if (addComma) {
+                string += ', ';
+            }
+            if (obj.hasOwnProperty(prop)) {
+                if (list) {
+                    if (SPECIAL_ARGS[prop]) continue;
+                    string += " --argument " + prop + "=" + obj[prop];
+                } else {    
+                    string += "'" + prop + "'" + ": '" + obj[prop] + "'";
+                    addComma = true;
+                }
+            }
+        }
+    
+        if (addComma) {
+            return '{' + string + '}';
+        } else {
+            if (list) {
+                return string;
+            } else {
+                return '';
+            }
+        }
+    };
+    
+    /**
+     * The following methods illustrate the QMF2 class query mechanism which returns
+     * the list of QMF Objects for the specified class that are currently present
+     * on the Broker. The Schema <qpid>/cpp/src/qpid/broker/management-schema.xml
+     * describes the properties and statistics of each Management Object.
+     * <p>
+     * One slightly subtle part of QMF is that certain Objects are associated via
+     * references, for example Binding contains queueRef and exchangeRef, which lets
+     * Objects link to each other using their _object_id property.
+     * <p>
+     * The implementation of these methods attempts to follow the same general flow
+     * as the equivalent method in the "canonical" python based qpid-config version
+     * but has the added complication that JavaScript is entirely asynchronous.
+     * The approach that has been taken is to use the correlator object that lets a
+     * callback function be registered via the "then" method and actually calls the
+     * callback when all of the requests specified in the request method have
+     * returned their results (which get passed as the callback parameter).
+     */
+    
+    var overview = function() {
+        brokerAgent.request(
+            // Send the QMF query requests for the specified classes.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'queue'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'exchange')
+        ).then(function(objects) {
+            var exchanges = objects.exchange;
+            var queues = objects.queue;
+            console.log("Total Exchanges: " + exchanges.length);
+            var etype = {};
+            for (var i = 0; i < exchanges.length; i++) {
+                var exchange = exchanges[i]._values;
+                if (!etype[exchange.type]) {
+                    etype[exchange.type] = 1;
+                } else {
+                    etype[exchange.type]++;
+                }
+            }
+            for (var typ in etype) {
+                var pad = Array(16 - typ.length).join(' ');
+                console.log(pad + typ + ": " + etype[typ]);
+            }
+    
+            console.log("\n   Total Queues: " + queues.length);
+            var durable = 0;
+            for (var i = 0; i < queues.length; i++) {
+                var queue = queues[i]._values;
+                if (queue.durable) {
+                    durable++;
+                }
+            }
+            console.log("        durable: " + durable);
+            console.log("    non-durable: " + (queues.length - durable));
+            brokerAgent.destroy();
+        });
+    };
+    
+    var exchangeList = function(filter) {
+        brokerAgent.request(
+            // Send the QMF query requests for the specified classes.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'exchange')
+        ).then(function(objects) {
+            var exchanges = objects.exchange;
+            var exMap = idMap(exchanges);
+            var caption1 = "Type      ";
+            var caption2 = "Exchange Name";
+            var maxNameLen = caption2.length;
+            var found = false;
+            for (var i = 0; i < exchanges.length; i++) {
+                var exchange = exchanges[i]._values;
+                if (filterMatch(exchange.name, filter)) {
+                    if (exchange.name.length > maxNameLen) {
+                        maxNameLen = exchange.name.length;
+                    }
+                    found = true;
+                }
+            }
+            if (!found) {
+                config._returnCode = 1;
+                return;
+            }
+    
+            var pad = Array(maxNameLen + 1 - caption2.length).join(' ');
+            console.log(caption1 + caption2 + pad + "  Attributes");
+            console.log(Array(maxNameLen + caption1.length + 13).join('='));
+    
+            for (var i = 0; i < exchanges.length; i++) {
+                var exchange = exchanges[i]._values;
+                if (config._ignoreDefault && !exchange.name) continue;
+                if (filterMatch(exchange.name, filter)) {
+                    var pad1 = Array(11 - exchange.type.length).join(' ');
+                    var pad2 = Array(maxNameLen + 2 - exchange.name.length).join(' ');
+                    var string = exchange.type + pad1 + exchange.name + pad2;
+                    var args = exchange.arguments ? exchange.arguments : {};
+                    if (exchange.durable) {
+                        string += ' --durable';
+                    }
+                    if (args[REPLICATE]) {
+                        string += ' --replicate=' + args[REPLICATE];
+                    }
+                    if (args[MSG_SEQUENCE]) {
+                        string += ' --sequence';
+                    }
+                    if (args[IVE]) {
+                        string += ' --ive';
+                    }
+                    if (exchange.altExchange) {
+                        string += ' --alternate-exchange=' + exMap[oid(exchange.altExchange)]._values.name;
+                    }
+                    console.log(string);
+                }
+            }
+            brokerAgent.destroy();
+        });
+    };
+    
+    var exchangeListRecurse = function(filter) {
+        brokerAgent.request(
+            // Send the QMF query requests for the specified classes.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'queue'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'exchange'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'binding')
+        ).then(function(objects) {
+            var exchanges = objects.exchange;
+            var bindings = objects.binding;
+            var queues = idMap(objects.queue);
+    
+            for (var i = 0; i < exchanges.length; i++) {
+                var exchange = exchanges[i];
+                var exchangeId = oid(exchange._object_id);
+                exchange = exchange._values;
+    
+                if (config._ignoreDefault && !exchange.name) continue;
+                if (filterMatch(exchange.name, filter)) {
+                    console.log("Exchange '" + exchange.name + "' (" + exchange.type + ")");
+                    for (var j = 0; j < bindings.length; j++) {
+                        var bind = bindings[j]._values;
+                        var exchangeRef = oid(bind.exchangeRef);
+    
+                        if (exchangeRef === exchangeId) {
+                            var queue = queues[oid(bind.queueRef)];
+                            var queueName = queue ? queue._values.name : "<unknown>";
+                            console.log("    bind [" + bind.bindingKey + "] => " + queueName + 
+                                        " " + renderObject(bind.arguments));
+                        }   
+                    }
+                }
+            }
+            brokerAgent.destroy();
+        });
+    };
+    
+    var queueList = function(filter) {
+        brokerAgent.request(
+            // Send the QMF query requests for the specified classes.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'queue'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'exchange')
+        ).then(function(objects) {
+            var queues = objects.queue;
+            var exMap = idMap(objects.exchange);
+            var caption = "Queue Name";
+            var maxNameLen = caption.length;
+            var found = false;
+            for (var i = 0; i < queues.length; i++) {
+                var queue = queues[i]._values;
+                if (filterMatch(queue.name, filter)) {
+                    if (queue.name.length > maxNameLen) {
+                        maxNameLen = queue.name.length;
+                    }
+                    found = true;
+                }
+            }
+            if (!found) {
+                config._returnCode = 1;
+                return;
+            }
+    
+            var pad = Array(maxNameLen + 1 - caption.length).join(' ');
+            console.log(caption + pad + "  Attributes");
+            console.log(Array(maxNameLen + caption.length + 3).join('='));
+    
+            for (var i = 0; i < queues.length; i++) {
+                var queue = queues[i]._values;
+                if (filterMatch(queue.name, filter)) {
+                    var pad2 = Array(maxNameLen + 2 - queue.name.length).join(' ');
+                    var string = queue.name + pad2;
+                    var args = queue.arguments ? queue.arguments : {};
+                    if (queue.durable) {
+                        string += ' --durable';
+                    }
+                    if (args[REPLICATE]) {
+                        string += ' --replicate=' + args[REPLICATE];
+                    }
+                    if (queue.autoDelete) {
+                        string += ' auto-del';
+                    }
+                    if (queue.exclusive) {
+                        string += ' excl';
+                    }
+                    if (args[FILESIZE]) {
+                        string += ' --file-size=' + args[FILESIZE];
+                    }
+                    if (args[FILECOUNT]) {
+                        string += ' --file-count=' + args[FILECOUNT];
+                    }
+                    if (args[MAX_QUEUE_SIZE]) {
+                        string += ' --max-queue-size=' + args[MAX_QUEUE_SIZE];
+                    }
+                    if (args[MAX_QUEUE_COUNT]) {
+                        string += ' --max-queue-count=' + args[MAX_QUEUE_COUNT];
+                    }
+                    if (args[POLICY_TYPE]) {
+                        string += ' --limit-policy=' + args[POLICY_TYPE].replace("_", "-");
+                    }
+                    if (args[LVQ_KEY]) {
+                        string += ' --lvq-key=' + args[LVQ_KEY];
+                    }
+                    if (args[QUEUE_EVENT_GENERATION]) {
+                        string += ' --generate-queue-events=' + args[QUEUE_EVENT_GENERATION];
+                    }
+                    if (queue.altExchange) {
+                        string += ' --alternate-exchange=' + exMap[oid(queue.altExchange)]._values.name;
+                    }
+                    if (args[FLOW_STOP_SIZE]) {
+                        string += ' --flow-stop-size=' + args[FLOW_STOP_SIZE];
+                    }
+                    if (args[FLOW_RESUME_SIZE]) {
+                        string += ' --flow-resume-size=' + args[FLOW_RESUME_SIZE];
+                    }
+                    if (args[FLOW_STOP_COUNT]) {
+                        string += ' --flow-stop-count=' + args[FLOW_STOP_COUNT];
+                    }
+                    if (args[FLOW_RESUME_COUNT]) {
+                        string += ' --flow-resume-count=' + args[FLOW_RESUME_COUNT];
+                    }
+                    if (args[MSG_GROUP_HDR_KEY]) {
+                        string += ' --group-header=' + args[MSG_GROUP_HDR_KEY];
+                    }
+                    if (args[SHARED_MSG_GROUP] === 1) {
+                        string += ' --shared-groups';
+                    }
+                    string += ' ' + renderObject(args, true);
+                    console.log(string);
+                }
+            }
+            brokerAgent.destroy();
+        });
+    };
+    
+    var queueListRecurse = function(filter) {
+        brokerAgent.request(
+            // Send the QMF query requests for the specified classes.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'queue'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'exchange'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'binding')
+        ).then(function(objects) {
+            var queues = objects.queue;
+            var bindings = objects.binding;
+            var exchanges = idMap(objects.exchange);
+    
+            for (var i = 0; i < queues.length; i++) {
+                var queue = queues[i];
+                var queueId = oid(queue._object_id);
+                queue = queue._values;
+    
+                if (filterMatch(queue.name, filter)) {
+                    console.log("Queue '" + queue.name + "'");
+                    for (var j = 0; j < bindings.length; j++) {
+                        var bind = bindings[j]._values;
+                        var queueRef = oid(bind.queueRef);
+    
+                        if (queueRef === queueId) {
+                            var exchange = exchanges[oid(bind.exchangeRef)];
+                            var exchangeName = "<unknown>";
+                            if (exchange) {
+                                exchangeName = exchange._values.name;
+                                if (exchangeName === '') {
+                                    if (config._ignoreDefault) continue;
+                                    exchangeName = "''";
+                                }
+                            }
+    
+                            console.log("    bind [" + bind.bindingKey + "] => " + exchangeName + 
+                                        " " + renderObject(bind.arguments));
+                        }   
+                    }
+                }
+            }
+            brokerAgent.destroy();
+        });
+    };
+    
+    /**
+     * The following methods implement adding and deleting various Broker Management
+     * Objects via QMF. Although <qpid>/cpp/src/qpid/broker/management-schema.xml
+     * describes the basic method schema, for example:
+     *   <method name="create" desc="Create an object of the specified type">
+     *     <arg name="type" dir="I" type="sstr" desc="The type of object to create"/>
+     *     <arg name="name" dir="I" type="sstr" desc="The name of the object to create"/>
+     *     <arg name="properties" dir="I" type="map" desc="Type specific object properties"/>
+     *     <arg name="strict" dir="I" type="bool" desc="If specified, treat unrecognised object properties as an error"/    >
+     *   </method>
+     *
+     *   <method name="delete" desc="Delete an object of the specified type">
+     *     <arg name="type" dir="I" type="sstr" desc="The type of object to delete"/>
+     *     <arg name="name" dir="I" type="sstr" desc="The name of the object to delete"/>
+     *     <arg name="options" dir="I" type="map" desc="Type specific object options for deletion"/>
+     *   </method>
+     *
+     * What the schema doesn't do however is to explain what the properties/options
+     * Map values actually mean, unfortunately these aren't documented anywhere so
+     * the only option is to look in the code, the best place to look is in:
+     * <qpid>/cpp/src/qpid/broker/Broker.cpp, the method Broker::ManagementMethod is
+     * the best place to start, then Broker::createObject and Broker::deleteObject
+     * even then it's pretty hard to figure out all that is possible.
+     */
+    
+    var handleMethodResponse = function(response, dontStop) {
+        if (response._arguments) {
+            //console.log(response._arguments);
+        } if (response._values) {
+            console.error("Exception from Agent: " + renderObject(response._values));
+        }
+        // Mostly we want to stop the Messenger Event loop and exit when a QMF method
+        // returns, but sometimes we don't, the dontStop flag prevents this behaviour.
+        if (!dontStop) {
+            brokerAgent.destroy();
+        }
+    }
+    
+    var addExchange = function(args) {
+        if (args.length < 2) {
+            usage();
+        }
+    
+        var etype = args[0];
+        var ename = args[1];
+        var declArgs = {};
+    
+        declArgs['exchange-type'] = etype;
+    
+        for (var a = 0; a < config._extra_arguments.length; a++) {
+            var r = config._extra_arguments[a].split('=');
+            declArgs[r[0]] = getValue(r);
+        }
+    
+        if (config._msgSequence) {
+            declArgs[MSG_SEQUENCE] = 1;
+        }
+    
+        if (config._ive) {
+            declArgs[IVE] = 1;
+        }
+    
+        if (config._altern_ex) {
+            declArgs['alternate-exchange'] = config._altern_ex;
+        }
+    
+        if (config._durable) {
+            declArgs['durable'] = 1;
+        }
+    
+        if (config._replicate) {
+            declArgs[REPLICATE] = config._replicate;
+        }
+    
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                brokerAgent.invokeMethod(broker, 'create', {
+                    "type":      "exchange",
+                    "name":       ename,
+                    "properties": declArgs,
+                    "strict":     true})
+            ).then(handleMethodResponse);
+        });
+    };
+    
+    var delExchange = function(args) {
+        if (args.length < 1) {
+            usage();
+        }
+    
+        var ename = args[0];
+    
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                brokerAgent.invokeMethod(broker, 'delete', {
+                    "type":   "exchange",
+                    "name":    ename})
+            ).then(handleMethodResponse);
+        });
+    };
+    
+    var addQueue = function(args) {
+        if (args.length < 1) {
+            usage();
+        }
+    
+        var qname = args[0];
+        var declArgs = {};
+    
+        for (var a = 0; a < config._extra_arguments.length; a++) {
+            var r = config._extra_arguments[a].split('=');
+            declArgs[r[0]] = getValue(r);
+        }
+    
+        if (config._durable) {
+            // allow the default fileCount and fileSize specified 
+            // in qpid config file to take prededence
+            if (config._fileCount) {
+                declArgs[FILECOUNT] = config._fileCount;
+            }
+            if (config._fileSize) {
+                declArgs[FILESIZE]  = config._fileSize;
+            }
+        }
+    
+        if (config._maxQueueSize != null) {
+            declArgs[MAX_QUEUE_SIZE] = config._maxQueueSize;
+        }
+    
+        if (config._maxQueueCount != null) {
+            declArgs[MAX_QUEUE_COUNT] = config._maxQueueCount;
+        }
+        
+        if (config._limitPolicy) {
+            if (config._limitPolicy === 'none') {
+            } else if (config._limitPolicy === 'reject') {
+                declArgs[POLICY_TYPE] = 'reject';
+            } else if (config._limitPolicy === 'ring') {
+                declArgs[POLICY_TYPE] = 'ring';
+            }
+        }
+    
+        if (config._lvq_key) {
+            declArgs[LVQ_KEY] = config._lvq_key;
+        }
+    
+        if (config._eventGeneration) {
+            declArgs[QUEUE_EVENT_GENERATION] = config._eventGeneration;
+        }
+    
+        if (config._flowStopSize != null) {
+            declArgs[FLOW_STOP_SIZE] = config._flowStopSize;
+        }
+    
+        if (config._flowResumeSize != null) {
+            declArgs[FLOW_RESUME_SIZE] = config._flowResumeSize;
+        }
+    
+        if (config._flowStopCount != null) {
+            declArgs[FLOW_STOP_COUNT] = config._flowStopCount;
+        }
+    
+        if (config._flowResumeCount != null) {
+            declArgs[FLOW_RESUME_COUNT] = config._flowResumeCount;
+        }
+    
+        if (config._msgGroupHeader) {
+            declArgs[MSG_GROUP_HDR_KEY] = config._msgGroupHeader;
+        }
+    
+        if (config._sharedMsgGroup) {
+            declArgs[SHARED_MSG_GROUP] = 1;
+        }
+    
+        if (config._altern_ex) {
+            declArgs['alternate-exchange'] = config._altern_ex;
+        }
+    
+        if (config._durable) {
+            declArgs['durable'] = 1;
+        }
+    
+        if (config._replicate) {
+            declArgs[REPLICATE] = config._replicate;
+        }
+    
+        // This block is a little complex and untidy, the real issue is that the
+        // correlator object isn't as good as a real Promise and doesn't support
+        // chaining of "then" calls, so where we have complex dependencies we still
+        // get somewhat into "callback hell". TODO improve the correlator.
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                brokerAgent.invokeMethod(broker, 'create', {
+                    "type":      "queue",
+                    "name":       qname,
+                    "properties": declArgs,
+                    "strict":     true})
+            ).then(function(response) {
+                if (config._start_replica) {
+                    handleMethodResponse(response, true); // The second parameter prevents exiting.
+                    // TODO test this stuff!
+                    brokerAgent.request(
+                        brokerAgent.getObjects('org.apache.qpid.ha', 'habroker') // Not sure if this is correct
+                    ).then(function(objects) {
+                        if (objects.habroker.length > 0) {
+                            var habroker = objects.habroker[0];
+                            brokerAgent.request(
+                                brokerAgent.invokeMethod(habroker, 'replicate', {
+                                    "broker": config._start_replica,
+                                    "queue":  qname})
+                            ).then(handleMethodResponse);
+                        } else {
+                            brokerAgent.destroy();
+                        }
+                    });
+                } else {
+                    handleMethodResponse(response);
+                }
+            });
+        });
+    };
+    
+    var delQueue = function(args) {
+        if (args.length < 1) {
+            usage();
+        }
+    
+        var qname = args[0];
+    
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                brokerAgent.invokeMethod(broker, 'delete', {
+                    "type":   "queue",
+                    "name":    qname,
+                    "options": {"if_empty":  config._if_empty,
+                                "if_unused": config._if_unused}})
+            ).then(handleMethodResponse);
+        });
+    };
+    
+    var snarf_header_args = function(args) {
+        if (args.length < 2) {
+            console.log("Invalid args to bind headers: need 'any'/'all' plus conditions");
+            return false;
+        }
+    
+        var op = args[0];
+        if (op === 'all' || op === 'any') {
+            kv = {};
+            var bindings = Array.prototype.slice.apply(args, [1]);
+            for (var i = 0; i < bindings.length; i++) {
+                var binding = bindings[i];
+                binding = binding.split(",")[0];
+                binding = binding.split("=");
+                kv[binding[0]] = binding[1];
+            }
+            kv['x-match'] = op;
+            return kv;
+        } else {
+            console.log("Invalid condition arg to bind headers, need 'any' or 'all', not '" + op + "'");
+            return false;
+        }
+    };
+    
+    var bind = function(args) {
+        if (args.length < 2) {
+            usage();
+        }
+    
+        var ename = args[0];
+        var qname = args[1];
+        var key   = '';
+    
+        if (args.length > 2) {
+            key = args[2];
+        }
+    
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker'),
+            brokerAgent.getObjects('org.apache.qpid.broker', 'exchange') // Get exchanges to look up exchange type.
+        ).then(function(objects) {
+            var exchanges = objects.exchange;
+    
+            var etype = '';
+            for (var i = 0; i < exchanges.length; i++) {
+                var exchange = exchanges[i]._values;
+                if (exchange.name === ename) {
+                    etype = exchange.type;
+                    break;
+                }
+            }
+    
+            // type of the xchg determines the processing of the rest of
+            // argv.  if it's an xml xchg, we want to find a file
+            // containing an x-query, and pass that.  if it's a headers
+            // exchange, we need to pass either "any" or all, followed by a
+            // map containing key/value pairs.  if neither of those, extra
+            // args are ignored.
+            var declArgs = {};
+            if (etype === 'xml') {
+    
+    
+            } else if (etype === 'headers') {
+                declArgs = snarf_header_args(Array.prototype.slice.apply(args, [3]));
+            }
+    //console.log(declArgs);
+    
+            if (typeof declArgs !== 'object') {
+                process.exit(1);
+            }
+    
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                brokerAgent.invokeMethod(broker, 'create', {
+                    "type":   "binding",
+                    "name":    ename + '/' + qname + '/' + key,
+                    "properties": declArgs,
+                    "strict":     true})
+            ).then(handleMethodResponse);
+        });
+    
+    /*
+    
+            ok = True
+            _args = {}
+            if not res:
+                pass
+            elif res.type == "xml":
+                # this checks/imports the -f arg
+                [ok, xquery] = snarf_xquery_args()
+                _args = { "xquery" : xquery }
+            else:
+                if res.type == "headers":
+                    [ok, op, kv] = snarf_header_args(args[3:])
+                    _args = kv
+                    _args["x-match"] = op
+    
+            if not ok:
+                sys.exit(1)
+    
+            self.broker.bind(ename, qname, key, _args)
+    */
+    
+    };
+    
+    var unbind = function(args) {
+        if (args.length < 2) {
+            usage();
+        }
+    
+        var ename = args[0];
+        var qname = args[1];
+        var key   = '';
+    
+        if (args.length > 2) {
+            key = args[2];
+        }
+    
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                brokerAgent.invokeMethod(broker, 'delete', {
+                    "type":   "binding",
+                    "name":    ename + '/' + qname + '/' + key})
+            ).then(handleMethodResponse);
+        });
+    };
+
+    /**
+     * The following methods are "generic" create and delete methods to for arbitrary
+     * Management Objects e.g. Incoming, Outgoing, Domain, Topic, QueuePolicy,
+     * TopicPolicy etc. use --argument k1=v1 --argument k2=v2 --argument k3=v3 to
+     * pass arbitrary arguments as key/value pairs to the Object being created/deleted,
+     * for example to add a topic object that uses the fanout exchange:
+     * ./qpid-config.js add topic fanout --argument exchange=amq.fanout \
+     * --argument qpid.max_size=1000000 --argument qpid.policy_type=ring
+     */
+    
+    var createObject = function(type, name, args) {
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                // Create an object of the specified type.
+                brokerAgent.invokeMethod(broker, 'create', {
+                    "type":       type,
+                    "name":       name,
+                    "properties": args,
+                    "strict":     true})
+            ).then(handleMethodResponse);
+        });
+    };
+    
+    var deleteObject = function(type, name, args) {
+        brokerAgent.request(
+            // We invoke the CRUD methods on the broker object.
+            brokerAgent.getObjects('org.apache.qpid.broker', 'broker')
+        ).then(function(objects) {
+            var broker = objects.broker[0];
+            brokerAgent.request(
+                // Create an object of the specified type and name.
+                brokerAgent.invokeMethod(broker, 'delete', {
+                    "type":    type,
+                    "name":    name,
+                    "options": args})
+            ).then(handleMethodResponse);
+        });
+    };
+    
+    /**
+     * This is a "generic" mechanism for listing arbitrary Management Objects.
+     */
+    var listObjects = function(type) {
+        brokerAgent.request(
+            brokerAgent.getObjects('org.apache.qpid.broker', type)
+        ).then(function(objects) {
+            // The correlator passes an object containing responses for all of the
+            // supplied requests so we index it by the supplied type to get our response.
+            objects = objects[type];
+    
+            // Collect available attributes, stringify the values and compute the max
+            // length of the value of each attribute so that we can later create a table.
+            var attributes = {};
+            var lengths = {};
+            for (var i = 0; i < objects.length; i++) {
+                var object = objects[i];
+                object = object._values;
+                for (var prop in object) {
+                    if (typeof object[prop] === 'object') { // Stringify Object properties.
+                        // Check if property is an ObjectID (reference property),
+                        // if so replace with the "name" part of the OID.
+                        if (object[prop]['_object_name']) {
+                            var parts = object[prop]['_object_name'].split(':');
+                            object[prop] = parts[parts.length - 1];
+                        } else {
+                            // Stringify general Object properties.
+                            object[prop] = renderObject(object[prop]);
+                        }
+                    } else {
+                        object[prop] = object[prop].toString(); // Stringify other property types.
+                    }
+    
+                    if (!lengths[prop] || object[prop].length > lengths[prop]) { // Compute lengths.
+                        lengths[prop] = object[prop].length > prop.length ? object[prop].length : prop.length;
+                    }
+    
+                    if (!config._list_properties || config._list_properties[prop]) { // Do we want this property?
+                        attributes[prop] = true;
+                    }
+                }
+            }
+    
+            if (!config._list_properties && DEFAULT_PROPERTIES[type]) {
+                attributes = DEFAULT_PROPERTIES[type];
+            }
+    
+            // Using the information we've previously prepared now render a table
+            // showing the required property values.
+            var desired = [];
+            var header = ''; // Table header showing the property names.
+            if (attributes['name']) {
+                desired.push('name');
+                delete attributes['name'];
+                header += 'name' + Array(lengths['name'] + 2 - 4).join(' ');
+            }
+    
+            for (var prop in attributes) {
+                desired.push(prop);
+                header += prop + Array(lengths[prop] + 2 - prop.length).join(' ');
+            }
+    
+            console.log("Objects of type '" + type + "'");
+            console.log(header);
+            console.log(Array(header.length).join('='));
+            for (var i = 0; i < objects.length; i++) {
+                var object = objects[i];
+                object = object._values;
+                var string = '';
+                for (var j = 0; j < desired.length; j++) {
+                    var key = desired[j];
+                    string += object[key] + Array(lengths[key] + 2 - object[key].length).join(' ');
+                }
+    
+                console.log(string);
+            }
+    
+            brokerAgent.destroy();
+        });
+    };
+    
+    var reloadAcl = function() {
+        brokerAgent.request(
+            brokerAgent.getObjects('org.apache.qpid.acl', 'acl')
+        ).then(function(objects) {
+            if (objects.acl.length > 0) {
+                var acl = objects.acl[0];
+                brokerAgent.request(
+                    // Create an object of the specified type.
+                    brokerAgent.invokeMethod(acl, 'reloadACLFile', {})
+                ).then(handleMethodResponse);
+            } else {
+                console.log("Failed: No ACL Loaded in Broker");
+                brokerAgent.destroy();
+            }
+        });
+    };
+    
+    
+    /********************* process command line options **********************/
+    
+    var params = [];
+    var extra_arguments = [];
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log(_usage);
+            console.log(_description);
+            console.log(_options);
+            process.exit(0);
+        }
+    
+        for (var i = 0; i < args.length; i++) {
+            var arg = args[i];
+            if (arg === '-r' || arg === '--recursive') {
+                config._recursive = true;
+            } else if (arg === '--ignore-default') {
+                config._ignoreDefault = true;
+            } else if (arg === '--durable') {
+                config._durable = true;
+            } else if (arg === '--shared-groups') {
+                config._sharedMsgGroup = true;
+            } else if (arg === '--sequence') {
+                config._sequence = true;
+            } else if (arg === '--ive') {
+                config._ive = true;
+            } else if (arg === '--force') {
+                config._if_empty = false;
+                config._if_unused = false;
+            } else if (arg === '--force-if-not-empty') {
+                config._if_empty = false;
+            } else if (arg === '--force-if-used') {
+                config._if_unused = false;
+            } else if (arg === '--sequence') {
+                config._msgSequence = true;
+            } else if (arg.charAt(0) === '-') {
+                i++;
+                var val = args[i];
+                if (arg === '-t' || arg === '--timeout') {
+                    config._connTimeout = parseInt(val);
+                    if (config._connTimeout === 0) {
+                        config._connTimeout = null;
+                    }
+                } else if (arg === '-b' || arg === '--broker' || arg === '-a' || arg === '--broker-addr') {
+                    if (val != null) {
+                        config._host = val;
+                    }
+                } else if (arg === '--alternate-exchange') {
+                    config._altern_ex = val;
+                } else if (arg === '--replicate') {
+                    if (!REPLICATE_LEVELS[val]) {
+                        console.error("Invalid replication level " + val + ", should be one of 'none', 'configuration'  or 'all'");
+                    }
+                    config._replicate = val;
+                } else if (arg === '--file-count') {
+                    config._fileCount = parseInt(val);
+                } else if (arg === '--file-size') {
+                    config._fileSize = parseInt(val);
+                } else if (arg === '--max-queue-size') {
+                    config._maxQueueSize = parseInt(val);
+                } else if (arg === '--max-queue-count') {
+                    config._maxQueueCount = parseInt(val);
+                } else if (arg === '--limit-policy') {
+                    config._limitPolicy = val;
+                } else if (arg === '--lvq-key') {
+                    config._lvq_key = val;
+                } else if (arg === '--generate-queue-events') {
+                    config._eventGeneration = parseInt(val);
+                } else if (arg === '--flow-stop-size') {
+                    config._flowStopSize = parseInt(val);
+                } else if (arg === '--flow-resume-size') {
+                    config._flowResumeSize = parseInt(val);
+                } else if (arg === '--flow-stop-count') {
+                    config._flowStopCount = parseInt(val);
+                } else if (arg === '--flow-resume-count') {
+                    config._flowResumeCount = parseInt(val);
+                } else if (arg === '--group-header') {
+                    config._msgGroupHeader = val;
+                } else if (arg === '--argument') {
+                    extra_arguments.push(val);
+                } else if (arg === '--start-replica') {
+                    config._start_replica = val;
+                } else if (arg === '--f' || arg === '--file') { // TODO Won't work in node.js
+                    config._file = val;
+                } else if (arg === '--show-property') {
+                    if (config._list_properties === null) {
+                        config._list_properties = {};
+                    }
+                    config._list_properties[val] = true;
+                }
+            } else {
+                params.push(arg);
+            }
+        }
+    }
+    
+    config._extra_arguments = extra_arguments;
+    
+    // The command only *actually* gets called when the QMF connection has actually
+    // been established so we wrap up the function we want to get called in a lambda.
+    var command = function() {overview();};
+    if (params.length > 0) {
+        var cmd = params[0];
+        var modifier = '';
+        if (params.length > 1) {
+            modifier = params[1];
+        }
+    
+        if (cmd === 'exchanges') {
+            if (config._recursive) {
+                command = function() {exchangeListRecurse(modifier);};
+            } else {
+                command = function() {exchangeList(modifier);};
+            }
+        } else if (cmd === 'queues') {
+            if (config._recursive) {
+                command = function() {queueListRecurse(modifier);};
+            } else {
+                command = function() {queueList(modifier);};
+            }
+        } else if (cmd === 'add') {
+            if (modifier === 'exchange') {
+                command = function() {addExchange(Array.prototype.slice.apply(params, [2]));};
+            } else if (modifier === 'queue') {
+                command = function() {addQueue(Array.prototype.slice.apply(params, [2]));};
+            } else if (params.length > 2) {
+                command = function() {createObject(modifier, params[2], config.getOptions());};
+            } else {
+                usage();
+            }
+        } else if (cmd === 'del') {
+            if (modifier === 'exchange') {
+                command = function() {delExchange(Array.prototype.slice.apply(params, [2]));};
+            } else if (modifier === 'queue') {
+                command = function() {delQueue(Array.prototype.slice.apply(params, [2]));};
+            } else if (params.length > 2) {
+                command = function() {deleteObject(modifier, params[2], {});};
+            } else {
+                usage();
+            }
+        } else if (cmd === 'bind') {
+            command = function() {bind(Array.prototype.slice.apply(params, [1]));};
+        } else if (cmd === 'unbind') {
+            command = function() {unbind(Array.prototype.slice.apply(params, [1]));};
+        } else if (cmd === 'reload-acl') {
+            command = function() {reloadAcl();};
+        } else if (cmd === 'list' && params.length > 1) {
+            command = function() {listObjects(modifier);};
+        } else {
+            usage();
+        }
+    }
+    
+    //console.log(config._host);
+    brokerAgent.addConnection(config._host, command);    
+} else {
+    console.error("qpid-config.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/recv.js b/examples/messenger/javascript/recv.js
new file mode 100644
index 0000000..ab5fcf1
--- /dev/null
+++ b/examples/messenger/javascript/recv.js
@@ -0,0 +1,69 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proton = require("qpid-proton");
+
+    var address = "amqp://~0.0.0.0";
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    var pumpData = function() {
+        while (messenger.incoming()) {
+            var t = messenger.get(message);
+
+            console.log("Address: " + message.getAddress());
+            console.log("Subject: " + message.getSubject());
+    
+            // body is the body as a native JavaScript Object, useful for most real cases.
+            //console.log("Content: " + message.body);
+    
+            // data is the body as a proton.Data Object, used in this case because
+            // format() returns exactly the same representation as recv.c
+            console.log("Content: " + message.data.format());
+    
+            messenger.accept(t);
+        }
+    };
+
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log("Usage: node recv.js <addr> (default " + address + ")");
+            process.exit(0);
+        }
+    
+        address = args[0];
+    }
+    
+    messenger.setIncomingWindow(1024);
+    
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.recv(); // Receive as many messages as messenger can buffer.
+    messenger.start();
+
+    messenger.subscribe(address);
+} else {
+    console.error("recv.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/send.html b/examples/messenger/javascript/send.html
new file mode 100644
index 0000000..c61e3f2
--- /dev/null
+++ b/examples/messenger/javascript/send.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html> <!-- HTML5 doctype -->
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+    http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<html>
+
+<head>
+	<title>Simple Proton Messenger Send Example</title>
+	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
+
+<!--
+  Import the Messenger Binding proton.js. Note that this simple example pulls
+  it from the node_modules/qpid-proton/lib, which is created by the build process
+  so that the node.js based examples "just work", in a real Web App you would
+  clearly need to copy the proton.js to your own server.
+
+  In actual fact the CMake build actually builds proton.js into the directory:
+  <build>/proton-c/bindings/javascript
+  where <build> is the build directory created to run cmake from, it is then
+  copied to the node_modules/qpid-proton/lib directory.
+
+  In this example we also set the global variable PROTON_TOTAL_MEMORY in order to
+  increase the virtual heap available to the emscripten compiled C runtime. It
+  is not really necessary to do this for this application as the default value
+  of 16777216 is fine, it is simply done here to illustrate how to do it.
+-->
+<script type="text/javascript">PROTON_TOTAL_MEMORY = 50000000;</script>
+<script type="text/javascript" src="../../../node_modules/qpid-proton/lib/proton.js"></script>
+
+<script type="text/javascript">
+var message = new proton.Message();
+var messenger = new proton.Messenger();
+
+var sendMessage = function() {
+    var address = document.getElementById("address").value;
+    var subject = document.getElementById("subject").value;
+    var body = document.getElementById("body").value;
+
+console.log("sendMessage");
+console.log("address = " + address);
+console.log("subject = " + subject);
+console.log("body = " + body);
+
+    message.setAddress(address);
+    message.setSubject(subject);
+    message.body = body;
+
+    messenger.put(message);
+};
+
+var errorHandler = function(error) {
+    console.log("Received error " + error);
+};
+
+messenger.on('error', errorHandler);
+messenger.start();
+
+</script>
+
+<style>
+body
+{
+	font: 13px/1.5 Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif;
+    overflow-x: hidden; /* Hide horizontal scrollbar */
+    background: #dddddd;
+}
+
+label
+{
+    display: block;
+	font-size: 17px;
+}
+
+input, textarea
+{
+	font-size: 13px;
+    margin-bottom: 10px;
+}
+</style>
+
+</head>
+
+<body>
+<div>
+    <label for="address">Address:</label>
+    <input type="text" id="address" size="40"
+           placeholder="amqp://user:password@host:port"
+           name="address" value="amqp://guest:guest@0.0.0.0" />
+</div>
+<div>    
+    <label for="subject">Subject:</label>
+    <input type="text" id="subject" size="40"
+           name="subject" value="Browser Message" />
+</div>
+<div>
+    <label for="body">Message:</label>
+    <textarea id="body" name="body" rows="4" cols="40">Hello From Browser!</textarea>
+</div>
+<div>
+    <input type="button" value="send" onclick="sendMessage()"/>
+</div>
+</body>
+
+</html>
diff --git a/examples/messenger/javascript/send.js b/examples/messenger/javascript/send.js
new file mode 100644
index 0000000..39d40bd
--- /dev/null
+++ b/examples/messenger/javascript/send.js
@@ -0,0 +1,105 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    // In this example we also set the global variable PROTON_TOTAL_MEMORY in order
+    // to increase the virtual heap available to the emscripten compiled C runtime.
+    // It is not really necessary to do this for this application as the default
+    // value of 16777216 is fine, it is simply done here to illustrate how to do it.
+    PROTON_TOTAL_MEMORY = 50000000;
+    var proton = require("qpid-proton");
+
+    var address = "amqp://0.0.0.0";
+    var subject = "UK.WEATHER";
+    var msgtext = "Hello World!";
+    var tracker = null;
+    var running = true;
+
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    // This is an asynchronous send, so we can't simply call messenger.put(message)
+    // at the end of the application as we would with a synchronous/blocking
+    // version, as the application would simply exit without actually sending.
+    // The following callback function (and messenger.setOutgoingWindow())
+    // gives us a means to wait until the consumer has received the message before
+    // exiting. The recv.js example explicitly accepts messages it receives.
+    var pumpData = function() {
+        var status = messenger.status(tracker);
+        if (status != proton.Status.PENDING) {
+            if (running) {
+                messenger.stop();
+                running = false;
+            } 
+        }
+
+        if (messenger.isStopped()) {
+            message.free();
+            messenger.free();
+        }
+    };
+
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log("Usage: node send.js [options] [message]");
+            console.log("Options:");
+            console.log("  -a <addr> The target address [amqp[s]://domain[/name]] (default " + address + ")");
+            console.log("  -s <subject> The message subject (default " + subject + ")");
+            console.log("message A text string to send.");
+            process.exit(0);
+        }
+
+        for (var i = 0; i < args.length; i++) {
+            var arg = args[i];
+            if (arg.charAt(0) === '-') {
+                i++;
+                var val = args[i];
+                if (arg === '-a') {
+                    address = val;
+                } else if (arg === '-s') {
+                    subject = val;
+                }
+            } else {
+                msgtext = arg;
+            }
+        }
+    }
+
+    console.log("Address: " + address);
+    console.log("Subject: " + subject);
+    console.log("Content: " + msgtext);
+
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.setOutgoingWindow(1024); // So we can track status of send message.
+    messenger.start();
+
+    message.setAddress(address);
+    message.setSubject(subject);
+    message.body = msgtext;
+
+    tracker = messenger.put(message);
+} else {
+    console.error("send.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/server.js b/examples/messenger/javascript/server.js
new file mode 100644
index 0000000..1a9eabb
--- /dev/null
+++ b/examples/messenger/javascript/server.js
@@ -0,0 +1,81 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Simple server for use with client.js illustrating request/response
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proton = require("qpid-proton");
+
+    var address = "amqp://~0.0.0.0";
+    var message = new proton.Message();
+    var reply   = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    var dispatch = function(request, response) {
+        var subject = request.getSubject();
+        if (subject) {
+            response.setSubject('Re: ' + subject);
+        }
+        response.properties = request.properties
+        console.log("Dispatched " + subject + " " + JSON.stringify(request.properties));
+    };
+
+    var pumpData = function() {
+        while (messenger.incoming()) {
+            var t = messenger.get(message);
+    
+            var replyTo = message.getReplyTo();
+            if (replyTo) {
+                console.log(replyTo);
+                reply.setAddress(replyTo);
+                reply.setCorrelationID(message.getCorrelationID());
+                reply.body = message.body;
+                dispatch(message, reply);
+                messenger.put(reply);
+            }
+    
+            messenger.accept(t);
+        }
+    };
+
+    var args = process.argv.slice(2);
+    if (args.length > 0) {
+        if (args[0] === '-h' || args[0] === '--help') {
+            console.log("Usage: node server.js <addr> (default " + address + ")");
+            process.exit(0);
+        }
+    
+        address = args[0];
+    }
+    
+    messenger.setIncomingWindow(1024);
+    
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.recv(); // Receive as many messages as messenger can buffer.
+    messenger.start();
+    
+    messenger.subscribe(address);
+} else {
+    console.error("server.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/spout.js b/examples/messenger/javascript/spout.js
new file mode 100644
index 0000000..16faa8e
--- /dev/null
+++ b/examples/messenger/javascript/spout.js
@@ -0,0 +1,71 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proton = require("qpid-proton");
+
+    console.log("spout not implemented yet");
+    process.exit(0);
+    
+    var address = "amqp://0.0.0.0";
+    var subject = "UK.WEATHER";
+    var msgtext = "Hello World!";
+    var tracker = null;
+    var running = true;
+    
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    function pumpData() {
+        var status = messenger.status(tracker);
+        if (status != proton.Status.PENDING) {
+console.log("status = " + status);
+
+            if (running) {
+console.log("stopping");
+                messenger.stop();
+                running = false;
+            } 
+        }
+    
+        if (messenger.isStopped()) {
+console.log("exiting");
+            message.free();
+            messenger.free();
+        }
+    };
+
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.setOutgoingWindow(1024);
+    messenger.start();
+
+    message.setAddress(address);
+    message.setSubject(subject);
+
+    message.body = msgtext;
+
+    tracker = messenger.put(message);
+} else {
+    console.error("spout.js should be run in Node.js");
+}
+
diff --git a/examples/messenger/javascript/ws2tcp.js b/examples/messenger/javascript/ws2tcp.js
new file mode 100755
index 0000000..abb78f2
--- /dev/null
+++ b/examples/messenger/javascript/ws2tcp.js
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * ws2tcp.js is a simple node.js library that proxies from a WebSocket to a TCP
+ * Socket or vice versa. It has minimal dependencies - the standard node.js net
+ * library and the ws WebSocket library (npm install ws).
+ * <p>
+ * Two fuctions are exported, ws2tcp proxies from a WebSocket to a TCP Socket and
+ * tcp2ws proxies from a TCP Socket to a WebSocket.
+ * @Author Fraser Adams
+ * @file
+ */
+
+var WebSocket = require('ws');
+var net = require('net');
+
+/**
+ * This function is shared by ws2tcp and tcp2ws and takes care of cleaning up
+ * and closing the WebSocket and Socket when things close down or error.
+ * @param sock the TCP Socket instance we're registering cleanup handlers for.
+ * @param ws the WebSocket instance we're registering cleanup handlers for.
+ */
+var registerCleanupCallbacks = function(sock, ws) {
+    var cleanup = function(sock, ws) {
+        sock.removeAllListeners('close');	
+        sock.end();
+        ws.removeAllListeners('close');
+        ws.close();
+    };
+
+    sock.on('close', function() {
+        cleanup(sock, ws);
+    });
+
+    sock.on('error', function (e) {
+        console.log("socket error: " + e.code);
+        cleanup(sock, ws);
+    });
+
+    ws.on('close', function() {
+        cleanup(sock, ws);
+    });
+
+    ws.on('error', function (e) {
+        console.log("websocket error: " + e.code);
+        cleanup(sock, ws);
+    });
+};
+
+/**
+ * This function establishes a proxy that listens on a specified TCP Socket port
+ * and proxies data to a WebSocket on the target host listening on the specified
+ * target port.
+ * @param lport the listen port.
+ * @param thost the target host.
+ * @param tport the target port.
+ * @param subProtocols a string containing a comma separated list of WebSocket sub-protocols.
+ */
+var tcp2ws = function(lport, thost, tport, subProtocols) {
+    var opts = null;
+    if (subProtocols) {
+        // The regex trims the string (removes spaces at the beginning and end,
+        // then splits the string by <any space>,<any space> into an Array.
+        subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+        opts = {'protocol': subProtocols.toString()};
+    }
+
+    var server = net.createServer(function(sock) {
+        var url = 'ws://' + thost + ':' + tport;
+        var ws = new WebSocket(url, opts);
+        var ready = false;
+        var buffer = [];
+
+        registerCleanupCallbacks(sock, ws);
+
+        sock.on('data', function(data) {
+            if (ready) {
+                ws.send(data);
+            } else {
+                buffer.push(data);
+            }
+        });
+
+        ws.on('open', function () {
+            if (buffer.length > 0) {
+                ws.send(Buffer.concat(buffer));
+            }
+            ready = true;
+            buffer = null;
+        });
+
+        ws.on('message', function(m) {
+            sock.write(m);	
+        });
+    });
+    server.listen(lport);
+};
+
+/**
+ * This function establishes a proxy that listens on a specified WebSocket port
+ * and proxies data to a TCP Socket on the target host listening on the specified
+ * target port.
+ * @param lport the listen port.
+ * @param thost the target host.
+ * @param tport the target port.
+ */
+var ws2tcp = function(lport, thost, tport) {
+    var server = new WebSocket.Server({port: lport});
+    server.on('connection', function(ws) {
+        var sock = net.connect(tport, thost);
+        var ready = false;
+        var buffer = [];
+
+        registerCleanupCallbacks(sock, ws);
+
+        ws.on('message', function(m) {
+            if (ready) {
+                sock.write(m);	
+            } else {
+                buffer.push(m);
+            }
+        });
+
+        sock.on('connect', function() {
+            if (buffer.length > 0) {
+                sock.write(Buffer.concat(buffer));
+            }
+            ready = true;
+            buffer = null;
+        });
+
+        sock.on('data', function(data) {
+            ws.send(data);
+        });
+    });
+    server.on('error', function(e) {
+        console.log("websocket server error: " + e.code);
+    });
+};
+
+// Export the two proxy functions.
+module.exports.ws2tcp = ws2tcp;
+module.exports.tcp2ws = tcp2ws;
+
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 96a0540..7872801 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -261,6 +261,19 @@
   add_subdirectory(bindings)
 endif (SWIG_FOUND)
 
+# Build the JavaScript language binding.
+# This is somewhat different to the other language bindings in that it does not use swig. It uses a C/C++ to
+# JavaScript cross-compiler called emscripten (https://github.com/kripken/emscripten). Emscripten takes C/C++
+# and compiles it into a highly optimisable subset of JavaScript called asm.js (http://asmjs.org/) that can be
+# aggressively optimised and run at near-native speed (usually between 1.5 to 10 times slower than native C/C++).
+option("BUILD_JAVASCRIPT" "Build JavaScript language binding" ON)
+if (BUILD_JAVASCRIPT)
+  find_package(Emscripten)
+  if (EMSCRIPTEN_FOUND)
+    add_subdirectory(bindings/javascript)
+  endif (EMSCRIPTEN_FOUND)
+endif (BUILD_JAVASCRIPT)
+
 add_subdirectory(docs/api)
 add_subdirectory(docs/man)
 add_subdirectory(../tests/tools/apps/c ../tests/tools/apps/c)
diff --git a/proton-c/bindings/javascript/CMakeLists.txt b/proton-c/bindings/javascript/CMakeLists.txt
new file mode 100644
index 0000000..38d039b
--- /dev/null
+++ b/proton-c/bindings/javascript/CMakeLists.txt
@@ -0,0 +1,272 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+ 
+# This file allows cross-compiling of proton to JavaScript using emscripten
+# (https://github.com/kripken/emscripten). As it is really a cross-compilation
+# (as opposed to a binding like with swig) the approach is rather different and
+# somewhat replicates the main build in the proton-c/CMakeLists.txt using quite
+# a bit of "copy and paste reuse".
+# TODO refactor this file (and proton-c/CMakeLists.txt) to keep the main
+# compilation and cross-compilation consistent.
+
+message(STATUS "Found emscripten, using that to build JavaScript binding")
+
+# Find and install the node.js packages that we might need. We can assume that
+# node.js itself is installed because Emscripten has a dependency on it.
+find_package(NodePackages)
+
+# Describe the target OS we are building to - Emscripten mimics the Linux platform.
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_VERSION 1)
+set(CMAKE_CROSSCOMPILING TRUE)
+
+# Specify the compiler to use for cross-compilation.
+set(CMAKE_C_COMPILER "${EMCC}")
+
+# Don't do compiler autodetection, since we are cross-compiling.
+include(CMakeForceCompiler)
+CMAKE_FORCE_C_COMPILER("${CMAKE_C_COMPILER}" Clang)
+
+# The Proton default build type is RelWithDebInfo, but for JavaScript the C debug
+# mechanism is irrelevant. If Debug is explicitly set we turn off optimisations
+# and don't run the closure compiler so any error/profiling messages are readable.
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+    message(STATUS "JavaScript build type is \"Debug\"")
+else()
+    set (CMAKE_BUILD_TYPE Release)
+    message(STATUS "JavaScript build type is \"Release\"")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
+    set(EMSCRIPTEN_LINK_OPTIMISATIONS "-O2 --closure 1")
+endif()
+
+# From this point we should be using emscripten compilation tools.
+message(STATUS "emscripten compilation environment:")
+message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
+
+
+# Set this to the proton-c directory, we're cross-compiling code from there.
+set(PN_PATH ${CMAKE_SOURCE_DIR}/proton-c)
+
+
+# TODO the OpenSSL stuff won't work for emscripten by default. It might well be
+# possible to compile it from source using emscripten (that's the standard practice
+# for libraries with emscripten) see https://github.com/kripken/emscripten/wiki/FAQ
+# "Q. How do I link against system libraries like SDL, boost, etc.?"
+# Though it might be more natural to simply use a TLS protected wss:// WebSocket URL.
+#  set(pn_driver_ssl_impl src/ssl/openssl.c)
+#  set(SSL_LIB ${OPENSSL_LIBRARIES})
+set(pn_driver_ssl_impl ${PN_PATH}/src/ssl/ssl_stub.c)
+
+# emscripten is Linux like so use the posix driver.
+set(pn_io_impl ${PN_PATH}/src/posix/io.c)
+set(pn_selector_impl ${PN_PATH}/src/posix/selector.c)
+set(pn_driver_impl ${PN_PATH}/src/posix/driver.c)
+
+
+# Generate encodings.h and protocol.h
+# It may be possible to use the ones generated for the main proton-c build but
+# qpid-proton-core has a dependency on the generated files, so I'm not sure if
+# it'll work without a command that can be run as a dependency. Probably best
+# do it this way when cross-compiling - though more copy'n'paste
+add_custom_command(
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/encodings.h
+  COMMAND python ${PN_PATH}/env.py PYTHONPATH=${PN_PATH} python ${PN_PATH}/src/codec/encodings.h.py > ${CMAKE_CURRENT_BINARY_DIR}/encodings.h
+  DEPENDS ${PN_PATH}/src/codec/encodings.h.py
+  )
+
+add_custom_command(
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/protocol.h
+  COMMAND python ${PN_PATH}/env.py PYTHONPATH=${PN_PATH} python ${PN_PATH}/src/protocol.h.py > ${CMAKE_CURRENT_BINARY_DIR}/protocol.h
+  DEPENDS ${PN_PATH}/src/protocol.h.py
+  )
+
+set(COMPILE_WARNING_FLAGS "-Werror -Wall -pedantic-errors -Wno-comment -Wno-warn-absolute-paths")
+
+# Explicitly set PLATFORM_DEFINITIONS to Linux ones for emscripten as we don't
+# want to inadvertently use Windows versions if we happen to be cross-compiling
+# from a Windows platform
+set(PLATFORM_DEFINITIONS "USE_CLOCK_GETTIME;USE_UUID_GENERATE;USE_STRERROR_R;USE_ATOLL")
+
+# The following is largely a copy from the the main proton-c/CMakeLists.txt.
+# The main difference is prefixing paths with ${PN_PATH}/ as we can't use a
+# relative path from this CMakeLists.txt.
+
+set(qpid-proton-platform
+  ${pn_io_impl}
+  ${pn_selector_impl}
+  ${pn_driver_impl}
+  ${PN_PATH}/src/platform.c
+  ${pn_driver_ssl_impl}
+  )
+
+set(qpid-proton-core
+  ${PN_PATH}/src/object/object.c
+  ${PN_PATH}/src/object/list.c
+  ${PN_PATH}/src/object/map.c
+  ${PN_PATH}/src/object/string.c
+  ${PN_PATH}/src/object/iterator.c
+  ${PN_PATH}/src/object/record.c
+
+  ${PN_PATH}/src/util.c
+  ${PN_PATH}/src/url.c
+  ${PN_PATH}/src/error.c
+  ${PN_PATH}/src/buffer.c
+  ${PN_PATH}/src/parser.c
+  ${PN_PATH}/src/scanner.c
+  ${PN_PATH}/src/types.c
+
+  ${PN_PATH}/src/framing/framing.c
+
+  ${PN_PATH}/src/codec/codec.c
+  ${PN_PATH}/src/codec/decoder.c
+  ${PN_PATH}/src/codec/encoder.c
+
+  ${PN_PATH}/src/dispatcher/dispatcher.c
+  ${PN_PATH}/src/engine/engine.c
+  ${PN_PATH}/src/events/event.c
+  ${PN_PATH}/src/transport/autodetect.c
+  ${PN_PATH}/src/transport/transport.c
+  ${PN_PATH}/src/message/message.c
+  ${PN_PATH}/src/sasl/sasl.c
+
+  ${PN_PATH}/src/messenger/messenger.c
+  ${PN_PATH}/src/messenger/subscription.c
+  ${PN_PATH}/src/messenger/store.c
+  ${PN_PATH}/src/messenger/transform.c
+  ${PN_PATH}/src/selectable.c
+
+  ${CMAKE_CURRENT_BINARY_DIR}/encodings.h
+  ${CMAKE_CURRENT_BINARY_DIR}/protocol.h
+  )
+
+set_source_files_properties(
+  ${qpid-proton-core}
+  PROPERTIES
+  COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_LANGUAGE_FLAGS}"
+  )
+
+set_source_files_properties(
+  ${qpid-proton-platform}
+  PROPERTIES
+  COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_PLATFORM_FLAGS}"
+  COMPILE_DEFINITIONS "${PLATFORM_DEFINITIONS}"
+  )
+
+# Compile Proton into LLVM bitcode which will be used later in the linking stage
+# of add_executable for compilation into Javascript.
+add_library(
+  qpid-proton-bitcode SHARED
+
+  ${qpid-proton-core}
+  ${qpid-proton-platform}
+  )
+
+set_target_properties(
+  qpid-proton-bitcode
+  PROPERTIES
+  VERSION   "${PN_LIB_SOMAJOR}.${PN_LIB_SOMINOR}"
+  SOVERSION "${PN_LIB_SOMAJOR}"
+  LINK_FLAGS "${CATCH_UNDEFINED}"
+  )
+
+
+# Compile the send-async.c and recv-async.c examples into JavaScript
+add_executable(send-async.js ${PN_PATH}/../examples/messenger/c/send-async.c)
+target_link_libraries(send-async.js qpid-proton-bitcode)
+
+add_executable(recv-async.js ${PN_PATH}/../examples/messenger/c/recv-async.c)
+target_link_libraries(recv-async.js qpid-proton-bitcode)
+
+set_target_properties(
+  send-async.js recv-async.js
+  PROPERTIES
+  COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_PLATFORM_FLAGS}"
+  RUNTIME_OUTPUT_DIRECTORY examples
+  DEPENDS ws
+
+  LINK_FLAGS "-s \"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\" -${EMSCRIPTEN_LINK_OPTIMISATIONS}"
+  )
+
+# Build the main JavaScript library called proton.js
+add_executable(proton.js binding.c)
+target_link_libraries(proton.js qpid-proton-bitcode)
+
+set_target_properties(
+  proton.js
+  PROPERTIES
+  COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_PLATFORM_FLAGS}"
+
+  # The --memory-init-file 0 stops emscripten emitting a separate memory
+  # initialization file, if this was enabled it makes packaging harder as
+  # applications would expect proton.js.mem to be served too. It's even more
+  # fiddly with node.js packages. This behaviour might be reinstated if the
+  # packaging mechanism improves.
+
+  LINK_FLAGS "-s \"EXPORT_NAME='proton'\" -s \"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\" ${EMSCRIPTEN_LINK_OPTIMISATIONS} --memory-init-file 0 --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/binding-open.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/module.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/error.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/messenger.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/subscription.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/message.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-uuid.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-symbol.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-described.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-array.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-typed-number.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-long.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/data-binary.js --post-js ${CMAKE_CURRENT_SOURCE_DIR}/binding-close.js -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=\"[]\" -s EXPORTED_FUNCTIONS=\"['_pn_get_version_major', '_pn_get_version_minor', '_pn_bytes', '_pn_error_text', '_pn_code', '_pn_messenger', '_pn_messenger_name', '_pn_messenger_set_blocking', '_pn_messenger_free', '_pn_messenger_errno', '_pn_messenger_error', '_pn_messenger_get_outgoing_window', '_pn_messenger_set_outgoing_window', '_pn_messenger_get_incoming_window', '_pn_messenger_set_incoming_window', '_pn_messenger_start', '_pn_messenger_stop', '_pn_messenger_stopped', '_pn_messenger_subscribe', '_pn_messenger_put', '_pn_messenger_status', '_pn_messenger_buffered', '_pn_messenger_settle', '_pn_messenger_outgoing_tracker', '_pn_messenger_work', '_pn_messenger_recv', '_pn_messenger_receiving', '_pn_messenger_get', '_pn_messenger_incoming_tracker', '_pn_messenger_incoming_subscription', '_pn_messenger_accept', '_pn_messenger_reject', '_pn_messenger_outgoing', '_pn_messenger_incoming',  '_pn_messenger_route', '_pn_messenger_rewrite', '_pn_messenger_set_passive', '_pn_messenger_selectable', '_pn_subscription_get_context', '_pn_subscription_set_context', '_pn_subscription_address', '_pn_message', '_pn_message_id', '_pn_message_correlation_id', '_pn_message_free', '_pn_message_errno', '_pn_message_error', '_pn_message_clear', '_pn_message_is_inferred', '_pn_message_set_inferred', '_pn_message_is_durable', '_pn_message_set_durable', '_pn_message_get_priority', '_pn_message_set_priority', '_pn_message_get_ttl', '_pn_message_set_ttl', '_pn_message_is_first_acquirer', '_pn_message_set_first_acquirer', '_pn_message_get_delivery_count', '_pn_message_set_delivery_count', '_pn_message_get_user_id', '_pn_message_set_user_id', '_pn_message_get_address', '_pn_message_set_address', '_pn_message_get_subject', '_pn_message_set_subject', '_pn_message_get_reply_to', '_pn_message_set_reply_to', '_pn_message_get_content_type', '_pn_message_set_content_type', '_pn_message_get_content_encoding', '_pn_message_set_content_encoding', '_pn_message_get_expiry_time', '_pn_message_set_expiry_time', '_pn_message_get_creation_time', '_pn_message_set_creation_time', '_pn_message_get_group_id', '_pn_message_set_group_id', '_pn_message_get_group_sequence', '_pn_message_set_group_sequence', '_pn_message_get_reply_to_group_id', '_pn_message_set_reply_to_group_id', '_pn_message_encode', '_pn_message_decode', '_pn_message_instructions', '_pn_message_annotations', '_pn_message_properties', '_pn_message_body', '_pn_data', '_pn_data_free', '_pn_data_error', '_pn_data_errno', '_pn_data_clear', '_pn_data_rewind', '_pn_data_next', '_pn_data_prev', '_pn_data_enter', '_pn_data_exit', '_pn_data_lookup', '_pn_data_narrow', '_pn_data_widen', '_pn_data_type', '_pn_data_encode', '_pn_data_decode', '_pn_data_put_list', '_pn_data_put_map', '_pn_data_put_array', '_pn_data_put_described', '_pn_data_put_null', '_pn_data_put_bool', '_pn_data_put_ubyte', '_pn_data_put_byte', '_pn_data_put_ushort', '_pn_data_put_short', '_pn_data_put_uint', '_pn_data_put_int', '_pn_data_put_char', '_pn_data_put_ulong', '_pn_data_put_long', '_pn_data_put_timestamp', '_pn_data_put_float', '_pn_data_put_double', '_pn_data_put_decimal32', '_pn_data_put_decimal64', '_pn_data_put_decimal128', '_pn_data_put_uuid', '_pn_data_put_binary', '_pn_data_put_string', '_pn_data_put_symbol', '_pn_data_get_list', '_pn_data_get_map', '_pn_data_get_array', '_pn_data_is_array_described', '_pn_data_get_array_type', '_pn_data_is_described', '_pn_data_is_null', '_pn_data_get_bool', '_pn_data_get_ubyte', '_pn_data_get_byte', '_pn_data_get_ushort', '_pn_data_get_short', '_pn_data_get_uint', '_pn_data_get_int', '_pn_data_get_char', '_pn_data_get_ulong', '_pn_data_get_long', '_pn_data_get_timestamp', '_pn_data_get_float', '_pn_data_get_double', '_pn_data_get_decimal32', '_pn_data_get_decimal64', '_pn_data_get_decimal128', '_pn_data_get_uuid', '_pn_data_get_binary', '_pn_data_get_string', '_pn_data_get_symbol', '_pn_data_copy', '_pn_data_format', '_pn_data_dump', '_pn_selectable_readable', '_pn_selectable_capacity', '_pn_selectable_writable', '_pn_selectable_pending', '_pn_selectable_is_terminal', '_pn_selectable_fd', '_pn_selectable_free']\""
+  )
+
+# This command packages up the compiled proton.js into a node.js package called
+# qpid-proton and copies it to the <proton>/node_modules directory. This allows
+# the node.js test and example programs to do proton = require("qpid-proton");
+add_custom_command(
+    TARGET proton.js
+    COMMAND ${CMAKE_COMMAND}
+            -E copy_directory 
+            ${CMAKE_CURRENT_SOURCE_DIR}/qpid-proton 
+            ${PROJECT_SOURCE_DIR}/node_modules/qpid-proton
+    COMMAND ${CMAKE_COMMAND}
+            -E copy
+            ${CMAKE_CURRENT_BINARY_DIR}/proton.js
+            ${PROJECT_SOURCE_DIR}/node_modules/qpid-proton/lib
+   COMMENT "Building qpid-proton package for node.js"
+)
+
+# The cleanall target removes the qpid-proton package from <proton>/node_modules
+add_custom_target(
+    cleanall
+    COMMAND echo "CLEAN NODE MODULES"
+    COMMAND ${CMAKE_COMMAND}
+            -E remove_directory
+            ${PROJECT_SOURCE_DIR}/node_modules/qpid-proton
+)
+
+# If the docs target is specified and the jsdoc3 package for node.js has been
+# installed then build the JavaScript API documentation.
+if (NODE_JSDOC_FOUND)
+    set(JSDOC_EXE ${PROJECT_SOURCE_DIR}/node_modules/.bin/jsdoc)
+
+    message(STATUS "Documentation Enabled. Using ${JSDOC_EXE} to build JavaScript docs")
+    add_custom_target(docs-js COMMAND ${JSDOC_EXE}
+                      -d ${CMAKE_CURRENT_BINARY_DIR}/html
+                      ${CMAKE_CURRENT_SOURCE_DIR}/module.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/error.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/messenger.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/subscription.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/message.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-uuid.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-symbol.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-described.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-array.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-typed-number.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-long.js
+                      ${CMAKE_CURRENT_SOURCE_DIR}/data-binary.js)
+    add_dependencies(docs docs-js)
+endif (NODE_JSDOC_FOUND)
+
diff --git a/proton-c/bindings/javascript/LICENSE b/proton-c/bindings/javascript/LICENSE
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/proton-c/bindings/javascript/LICENSE
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/proton-c/bindings/javascript/README b/proton-c/bindings/javascript/README
new file mode 100644
index 0000000..8bfde56
--- /dev/null
+++ b/proton-c/bindings/javascript/README
@@ -0,0 +1,426 @@
+Qpid Proton JavaScript Language Bindings
+========================================
+
+The code contained herein provides JavaScript language bindings for working
+with the Qpid Proton AMQP 1.0 protocol engine and messenger library.
+
+Important Note - Modern Browser Needed
+======================================
+
+The JavaScript binding requires ArrayBuffer/TypedArray and WebSocket support.
+Both of these are available in most "modern" browser versions. The author has
+only tried running on FireFox and Chrome, though recent Safari, Opera and IE10+
+*should* work too - YMMV. It might be possible to polyfill for older browsers
+but the author hasn't tried this.
+
+Important Note - WebSocket Transport!!!
+=======================================
+
+Before going any further it is really important to realise that the JavaScript
+bindings to Proton are somewhat different to the bindings for other languages
+because of the restrictions of the execution environment. In particular it is
+very important to note that the JavaScript bindings by default use a WebSocket
+transport and not a TCP transport, so whilst it's possible to create Server style
+applications that clients can connect to (e.g. recv.js and send.js) note that:
+
+JavaScript clients cannot *directly* talk to "normal" AMQP applications such as
+qpidd or (by default) the Java Broker because they use a standard TCP transport.
+
+This is a slightly irksome issue, but there's no getting away from it because
+it's a security restriction imposed by the browser environment.
+
+
+At the moment even for Node.js we are limited to using a WebSocket transport, but
+it is on the author's "TODO" list to look at providing a means to use either a
+WebSocket transport or a native TCP transport (via node's net library). It should
+also be possible to use native TCP for Chrome "packaged apps", but again this is
+only on the TODO list so if you want to talk to a "normal" AMQP application you
+must live with the WebSocket constraints.
+
+Option 1. proxy from WebSockets to TCP sockets. The application
+<proton>/examples/messenger/javascript/proxy.js
+is a simple Node.js WebSocket<->TCP Socket proxy, simply doing:
+
+node proxy.js
+
+will stand up a proxy listening by default on WebSocket port 5673 and forwarding
+to TCP port 5672 (this is configurable, for options do: node proxy.js -h)
+
+Rather than using a stand-alone proxy it is possible to have applications stand
+up their own proxy (where lport = listen port, thost = target host and
+tport = target port):
+
+var proxy = require('./ws2tcp.js');
+proxy.ws2tcp(lport, thost, tport);
+
+For talking to the C++ broker unfortunately proxying is currently the only option
+as qpidd does not have a WebSocket transport.
+
+Option 2. The Java Broker's WebSocket transport.
+Recent releases of the Qpid Java Broker provide a native WebSocket transport which
+means that the JavaScript binding can talk to it with no additional requirements.
+It is necessary to configure the Java Broker as the WebSocket transport is not
+enabled by default. In <qpid-work>/config.json in the "ports" array you need to add:
+
+{
+    "authenticationProvider" : "passwordFile",
+    "name" : "AMQP-WS",
+    "port" : "5673",
+    "transports" : [ "WS" ]
+}
+
+This sets the JavaBroker to listen on WebSocket port 5673 similar to the proxy.
+
+
+One gotcha that still bites the author *** DO NOT FORGET *** that you will be
+using ports that you are not used to!! If you are not connecting check that the
+proxy is running and that you are specifying the right ports. I still mess up :-(
+
+WebRTC Transport
+================
+
+A WebRTC Transport is supported by emscripten, though the author has not tried it.
+If you wan to play with this you are very much on your own at the moment YMMV.
+
+This is configured by adding to the LINK_FLAGS in CMakeLists.txt
+-s \"SOCKET_WEBRTC=1\"
+
+  /* WebRTC sockets supports several options on the Module object.
+
+     * Module['host']: true if this peer is hosting, false otherwise
+     * Module['webrtc']['broker']: hostname for the p2p broker that this peer should use
+     * Module['webrtc']['session']: p2p session for that this peer will join, or undefined if this peer is hosting
+     * Module['webrtc']['hostOptions']: options to pass into p2p library if this peer is hosting
+     * Module['webrtc']['onpeer']: function(peer, route), invoked when this peer is ready to connect
+     * Module['webrtc']['onconnect']: function(peer), invoked when a new peer connection is ready
+     * Module['webrtc']['ondisconnect']: function(peer), invoked when an existing connection is closed
+     * Module['webrtc']['onerror']: function(error), invoked when an error occurs
+   */
+
+If you wanted to play with these you'd likely have to tweak the module.js code in
+<proton>/proton-c/bindings/javascript
+
+The emscripten documentation is a bit light on the WebRTC Transport too, though
+
+emscripten/tests/test_sockets.py
+emscripten/tests/sockets/webrtc_host.c
+emscripten/tests/sockets/webrtc_peer.c
+emscripten/tests/sockets/p2p/broker/p2p-broker.js
+emscripten/tests/sockets/p2p/client/p2p-client.js
+
+Look like they provide a starting point.
+Very much TODO......
+
+
+Creating The Bindings
+=====================
+
+To generate the JavaScript bindings we actually cross-compile from proton-c
+
+You will need to have emscripten (https://github.com/kripken/emscripten) installed
+to do the cross-compilation and in addition you will require a few things that
+emscripten itself depends upon.
+
+http://kripken.github.io/emscripten-site/docs/building_from_source/index.html#installing-from-source
+http://kripken.github.io/emscripten-site/docs/building_from_source/toolchain_what_is_needed.html
+provide instructions for installing emscripten and the "fastcomp" LLVM backend.
+This approach lets users use the "bleeding edge" version of emscripten on the
+"incoming" branch (pretty much analogous to building qpid/proton off svn trunk).
+This is the approach that the author of the JavaScript Bindings tends to use.
+
+
+http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
+provides some fairly easy to follow instructions for getting started on several
+platforms the main dependencies are as follows (on Windows the SDK includes these):
+
+* The Emscripten code, from github (git clone git://github.com/kripken/emscripten.git).
+* LLVM with Clang. Emscripten uses LLVM and Clang, but at the moment the JavaScript
+  back-end for LLVM is off on a branch so you can't use a stock LLVM/Clang.
+  http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html
+  http://kripken.github.io/emscripten-site/docs/building_from_source/building_fastcomp_manually_from_source.html#building-fastcomp-from-source
+  has lots of explanation and some easy to follow instructions for downloading
+  and building fastcomp
+* Node.js (0.8 or above; 0.10.17 or above to run websocket-using servers in node)
+* Python 2.7.3
+* Java is required in order to use the Closure Compiler to minify the code.
+  
+
+If you haven't run Emscripten before it's a good idea to have a play with the
+tutorial here:
+http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html
+
+
+
+when you are all set up with emscripten and have got the basic tests in the
+tutorial running building Proton should be simple, simply go to the Proton root
+directory and follow the main instructions in the README there, in precis (from
+the root directory) it's:
+
+  mkdir build
+  cd build
+  cmake ..
+  make
+
+and you should be all set, to test it's all working do (from the build directory):
+  cd proton-c/bindings/javascript/examples
+
+  node recv-async.js
+
+in one window and
+
+  node send-async.js
+
+in another.
+
+These examples are actually JavaScript applications that have been directly
+compiled from recv-async.c and send-async.c in <proton>/examples/messenger/c
+if you'd prefer to write applications in C and compile them to JavaScript that
+is a perfectly valid approach and these examples provide a reasonable starting
+point for doing so.
+
+Documentation
+=============
+
+When you've successfully got a working build do:
+
+  make docs
+
+Which will make all of the proton documentation including the JavaScript docs.
+If successful the JSDoc generated documentation should be found here:
+
+<proton>/build/proton-c/bindings/javascript/html/index.html
+
+
+Using "native" JavaScript
+=========================
+
+The examples in <proton>/examples/messenger/javascript are the best starting point.
+
+In practice the examples follow a fairly similar pattern to the Python bindings
+the most important thing to bear in mind though is that JavaScript is completely
+asynchronous/non-blocking, which can catch the unwary.
+
+An application follows the following (rough) steps:
+
+1. (optional) Set the heap size.
+It's important to realise that most of the library code is compiled C code and
+the runtime uses a "virtual heap" to support the underlying malloc/free. This is
+implemented internally as an ArrayBuffer with a default size of 16777216.
+
+To allocate a larger heap an application must set the PROTON_TOTAL_MEMORY global.
+In Node.js this would look like (see send.js):
+PROTON_TOTAL_MEMORY = 50000000; // Note no var - it needs to be global.
+
+In a browser it would look like (see send.html):
+<script type="text/javascript">PROTON_TOTAL_MEMORY = 50000000;</script>
+
+2. Load the library and create a message and messenger.
+In Node.js this would look like (see send.js):
+var proton = require("qpid-proton");
+var message = new proton.Message();
+var messenger = new proton.Messenger();
+
+In a browser it would look like (see send.html):
+<script type="text/javascript" src="../../../node_modules/qpid-proton/lib/proton.js"></script>
+
+<script type="text/javascript">
+var message = new proton.Message();
+var messenger = new proton.Messenger();
+....
+
+3. Set up event handlers as necessary.
+
+messenger.on('error', <error callback>);
+messenger.on('work', <work callback>);
+messenger.on('subscription', <subscription callback>);
+
+
+The work callback is triggered on WebSocket events, so in general you would use
+this to send and receive messages, for example in recv.js we have:
+
+var pumpData = function() {
+    while (messenger.incoming()) {
+        var t = messenger.get(message);
+
+        console.log("Address: " + message.getAddress());
+        console.log("Subject: " + message.getSubject());
+
+        // body is the body as a native JavaScript Object, useful for most real cases.
+        //console.log("Content: " + message.body);
+
+        // data is the body as a proton.Data Object, used in this case because
+        // format() returns exactly the same representation as recv.c
+        console.log("Content: " + message.data.format());
+
+        messenger.accept(t);
+    }
+};
+
+messenger.on('work', pumpData);
+
+
+The subscription callback is triggered when the address provided in a call to
+messenger.subscribe(<address>);
+
+Gets resolved. An example of its usage can be found in qpid-config.js which is
+a fully functioning and complete port of the python qpid-config tool. It also
+illustrates how to do asynchronous request/response based applications.
+
+Aside from the asynchronous aspects the rest of the API is essentially the same
+as the Python binding aside from minor things such as camel casing method names etc.
+
+Serialisation/Deserialisation, Types etc.
+=========================================
+
+The JavaScript binding tries to be as simple, intuitive and natural as possible
+so when sending a message all native JavaScript types including Object literals
+and Arrays are transparently supported, for example.
+
+var message = new proton.Message();
+message.setAddress('amqp://localhost');
+message.setSubject('UK.NEWS');
+message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
+
+
+The main thing to bear in mind is that (particularly for sending messages) we
+may need to use "adapters" to make sure values are correctly interpreted and
+encoded to the correct type in the AMQP type system. This is especially important
+when interoperating with a peer written in a strongly typed language (C/C++/Java).
+
+Some examples of available types follow:
+
+// UUID
+message.body = new proton.Data.Uuid();
+
+// AMQP Symbol
+message.body = new proton.Data.Symbol("My Symbol");
+
+// Binary data (created from a gibberish String in this case).
+message.body = new proton.Data.Binary("Monkey Bathпогромзхцвбнм");
+
+// Binary data (Get a Uint8Array view of the data and directly access that).
+message.body = new proton.Data.Binary(4);
+var buffer = message.body.getBuffer();
+buffer[0] = 65;
+buffer[1] = 77;
+buffer[2] = 81;
+buffer[3] = 80;
+
+// Binary Data (Created from an Array, you can use an ArrayBuffer/TypedArray too).
+message.body = new proton.Data.Binary([65, 77, 81, 80]);
+
+
+Note that the implementation of proton.Data.Binary tries to minimise copying so
+it accesses the internal emscripten heap *directly* this requires memory management
+which is mostly handled transparently, but users need to be aware that the
+underlying memory is "owned" by the Message Object, so if Binary data needs to
+be maintained after the next call to messenger.get(message); it must be
+*explicitly* copied. For more detail do "make docs" and see:
+<proton>/build/proton-c/bindings/javascript/html/proton.Data.Binary.html
+
+
+// AMQP Described (value, descriptor)
+message.body = new proton.Data.Described('persian, 'com.cheezburger.icanhas');
+
+// AMQP Timestamp maps to native JavaScript Date.
+message.body = new Date();
+
+// Various AMQP Array examples.
+message.body = new proton.Data.Array('INT', [1, 3, 5, 7], "odd numbers");
+message.body = new proton.Data.Array('UINT', [1, 3, 5, 7], "odd");
+message.body = new proton.Data.Array('ULONG', [1, 3, 5, 7], "odd");
+message.body = new proton.Data.Array('FLOAT', [1, 3, 5, 7], "odd");
+message.body = new proton.Data.Array('STRING', ["1", "3", "5", "7"], "odd");
+
+// A JavaScript TypedArray will map directly to and from an AMQP Array of the
+// appropriate type (Internally sets a descriptor of 'TypedArray').
+message.body = new Uint8Array([1, 3, 5, 7]);
+
+// UUID Array
+message.body = new proton.Data.Array('UUID', [new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid()], "unique");
+
+// Null
+message.body = null;
+
+// Boolean
+message.body = true;
+
+// Native JavaScript Array maps to an AMQP List
+message.body = ['Rod', 'Jane', 'Freddy'];
+
+// Native JavaScript Object maps to an AMQP Map
+message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
+
+// JavaScript only has a "number" type so the binding provides "decorator"
+// methods added to the JavaScript Number class. To access this from number
+// primitives it is necessary to either use braces or use a "double dot" so that
+// the interpreter can disambiguate from a simple decimal point. The binding will
+// attempt to use the correct type such that message.body = 2147483647; would be
+// sent as an AMQP integer, but because of the way JavaScript coerces integers
+// message.body = 2147483647.0; would also be sent as an AMQP integer because
+// 2147483647.0 gets transparently conveted to 2147483647 by the interpreter, so
+// to explicitly send this as an AMQP float we'd need to do:
+// message.body = 2147483647.0.float();
+
+// Some more number examples:
+message.body = 66..char();  // char - note double dot. (66).char(); works too.
+message.body = 2147483647;  // int
+message.body = -2147483649; // long
+message.body = 12147483649; // long
+message.body = (12147483649).long(); // long
+message.body = (17223372036854778000).ulong(); // ulong
+message.body = (121474.836490).float(); // float
+message.body = 12147483649.0.float(); // float
+message.body = (4294967296).uint(); // uint
+message.body = (255).ubyte(); // ubyte
+
+Note too that floats are subject to a loss of precision
+
+
+Fortunately most of these quirks only affect serialisation.when the binding
+receives a message it will attempt to decode it into the most "natural" native
+JavaScript type.
+
+
+One additional decoding "quirk" can be caused by C++ qpid::messaging clients. It
+is unfortunately quite common for C++ clients to incorrectly encode Strings as
+AMQP Binary by neglecting to provide an encoding. The QMF Management Agent is one
+such culprit. This is a bit of a pain, especially because of proton.Data.Binary
+memory management quirks and having to remember to explicitly copy the data
+on each call to messenger.get(message); In order to cater for this an overloaded
+messenger.get(message, true); has been provided. Setting the second parameter to
+true forces any received Binary payloads to be decoded as Strings. If you know
+that producers might behave in this way and you are not expecting any "real"
+Binary data from the producer this convenience mechanism results in nice clean
+JavaScript Objects being received and is extremely useful for things like QMF.
+
+JSON
+====
+
+As well as allowing native JavaScript Objects and Arrays to be transparently
+serialised and deserialised via the AMQP type system it is also possible to
+serialise/deserialise as JSON.
+
+message.setAddress('amqp://localhost');
+message.setContentType('application/json');
+message.body = {array: [1, 2, 3, 4], object: {name: "John Smith", age: 65}};
+
+On the wire the above will be encoded as an opaque binary in an AMQP data section
+but will be deserialised into a JavaScript Object in exactly the same was as the
+previous examples that use the AMQP type system.
+
+SUPPORT
+=======
+
+To report bugs in the bindings, or to request an enhancement, please file
+a tracker request:
+
+    https://issues.apache.org/jira/browse/PROTON
+
+The main support channel is the qpid-users mailing list, see:
+
+    http://qpid.apache.org/discussion.html#mailing-lists
+
+You can also directly interact with the development team and other users
+in the #qpid channel on irc.freenode.net.
+
diff --git a/proton-c/bindings/javascript/TODO b/proton-c/bindings/javascript/TODO
new file mode 100644
index 0000000..092ee2e
--- /dev/null
+++ b/proton-c/bindings/javascript/TODO
@@ -0,0 +1,49 @@
+Qpid Proton JavaScript Language Bindings TODO List
+==================================================
+
+Network code is currently limited to a WebSocket transport, including for Node.js
+It would be good to allow a configurable transport so that Node.js and Chrome
+packaged apps could use native TCP sockets.
+
+The JavaScript binding is pure JavaScript, that has been  trans-compiled from C
+to JavaScript using emscripten. This allows the same code to be used in a browser
+and Node.js, but it potentially has a performance penalty in Node.js. An alternative
+for Node.js might be to build a SWIG binding (recent versions of SWIG support
+JavaScript). This should be viewed as a complementary not competing approach as
+it would only work for environments like Node.js and definitely *not* browser
+environments which clearly require pure JavaScript.
+
+Optimisation are enabled for compiling and linking but there hasn't been any
+profiling done yet. The binding code *shouldn't* be the bottleneck but it's
+always possible that I messed up.
+
+Error handling is nowhere near as good as it should be, though this is mostly
+because Messenger itself is a bit lacking on the error handling/recovery front.
+
+Although described as "Proton" this is currently a JavaScript binding for Messenger
+and associated Message & Data classes. There has been some talk on the user list
+of an alternative reactive API based on proton Engine. This might ultimately be
+a better fit for JavaScript but it is very much in its infancy and I haven't
+really looked at it yet.
+
+proton-j seems to use hawt-dispatch, which is modelled after Grand Central
+Dispatch so I need to work out what it's using it do do and whether there are
+parallels in proton-c
+
+Although the WebSocket transport uses the sub-protocol 'AMQPWSB10' as specified
+in http://docs.oasis-open.org/amqp-bindmap/amqp-wsb/v1.0/amqp-wsb-v1.0.html
+section 2.1 is is not technically compliant with the spec. as the AMQP data is
+created by the proton-c code, which produces a data-stream for the TCP transport
+whereas the WebSocket spec. seems to want to make use of the fact that WebSocket
+is a frame based transport (whereas TCP is not). This is quite hard to resolve
+as the binding simply sends the contents of the octet buffer created by proton
+over the transport and thus to make this binding compliant with the spec. would
+require a change to the underlying proton-c code! It is possible that this may be
+done in future as any SCTP would require the ability to push AMQP frames too.
+In the mean time fortunately the Java Broker WebSocket transport is actually
+tolerant of this off-spec. behaviour. My personal view is that both approaches
+should be valid and in particular using the standard TCP framing means that it
+is straightforward to create WebSocket<->TCP proxies, which is useful given that
+only the Java Broker currently has a native WebSocket transport.
+
+
diff --git a/proton-c/bindings/javascript/binding-close.js b/proton-c/bindings/javascript/binding-close.js
new file mode 100644
index 0000000..07b68c2
--- /dev/null
+++ b/proton-c/bindings/javascript/binding-close.js
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * These values are essentially constants sitting in the proton namespace
+ * that is to say they will be exported via:
+ * proton.VERSION_MAJOR
+ * proton.VERSION_MINOR
+ * We have to set them after pn_get_version_major/pn_get_version_minor have been
+ * defined so we must do it here in binding-close.js as it's a --post-js block.
+ */
+Module['VERSION_MAJOR'] = _pn_get_version_major();
+Module['VERSION_MINOR'] = _pn_get_version_minor();
+
+})(); // End of self calling lambda used to wrap library.
+
diff --git a/proton-c/bindings/javascript/binding-open.js b/proton-c/bindings/javascript/binding-open.js
new file mode 100644
index 0000000..40e1b12
--- /dev/null
+++ b/proton-c/bindings/javascript/binding-open.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+(function() { // Start of self-calling lambda used to avoid polluting global namespace.
diff --git a/proton-c/bindings/javascript/binding.c b/proton-c/bindings/javascript/binding.c
new file mode 100644
index 0000000..ecc65dc
--- /dev/null
+++ b/proton-c/bindings/javascript/binding.c
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*
+ * This file is largely just a stub, we're actually creating a JavaScript library
+ * rather than an executable so most of the  work is done at the link stage.
+ * We do however need to link the libqpid-proton-bitcode.so with *something* and
+ * this is it. This file also provides a way to pass any global variable or
+ * #defined values to the JavaScript binding by providing wrapper functions.
+ */
+#include <stdio.h>
+#include <proton/version.h>
+
+// To access #define values in JavaScript we need to wrap them in a function.
+int pn_get_version_major() {return PN_VERSION_MAJOR;}
+int pn_get_version_minor() {return PN_VERSION_MINOR;}
+
diff --git a/proton-c/bindings/javascript/data-array.js b/proton-c/bindings/javascript/data-array.js
new file mode 100644
index 0000000..6f9776d
--- /dev/null
+++ b/proton-c/bindings/javascript/data-array.js
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.Array                             */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * TODO make this behave more like a native JavaScript Array: http://www.bennadel.com/blog/2292-extending-javascript-arrays-while-keeping-native-bracket-notation-functionality.htm
+ * Create a proton.Data.Array.
+ * @classdesc
+ * This class represents an AMQP Array.
+ * @constructor proton.Data.Array
+ * @param {string|number} type the type of the Number either as a string or number.
+ *        Stored internally as a string corresponding to one of the TypeNames.       
+ * @param {Array|TypedArray} elements the Native JavaScript Array or TypedArray that we wish to serialise.
+ * @param {object} descriptor an optional object describing the type.
+ */
+Data['Array'] = function(type, elements, descriptor) { // Data.Array Constructor.
+    // This block caters for an empty Array or a Described empty Array.
+    if (arguments.length < 2) {
+        descriptor = type;
+        type = 'NULL';
+        elements = [];
+    }
+
+    this['type']  = (typeof type === 'number') ? Data['TypeNames'][type] : type;
+    this['elements'] = elements;
+    this['descriptor'] = descriptor;
+};
+
+/**
+ * @method toString
+ * @memberof! proton.Data.Array#
+ * @returns {string} the String form of a {@link proton.Data.Array}.
+ */
+Data['Array'].prototype.toString = function() {
+    var descriptor = (this['descriptor'] == null) ? '' : ':' + this['descriptor'];
+    return this['type'] + 'Array' + descriptor + '[' + this['elements'] + ']';
+};
+
+/**
+ * @method valueOf
+ * @memberof! proton.Data.Array#
+ * @returns {Array} the elements of the {@link proton.Data.Array}.
+ */
+Data['Array'].prototype.valueOf = function() {
+    return this['elements'];
+};
+
+/**
+ * Compare two instances of proton.Data.Array for equality. N.B. this method
+ * compares the value of every Array element so its performance is O(n).
+ * @method equals
+ * @memberof! proton.Data.Array#
+ * @param {proton.Data.Array} rhs the instance we wish to compare this instance with.
+ * @returns {boolean} true iff the two compared instances are equal.
+ */
+Data['Array'].prototype['equals'] = function(rhs) {
+    if (rhs instanceof Data['Array'] &&
+        // Check the string value of the descriptors.
+        (('' + this['descriptor']) === ('' + rhs['descriptor'])) &&
+        (this['type'] === rhs['type'])) {
+        var elements = this['elements'];
+        var relements = rhs['elements'];
+        var length = elements.length;
+        if (length === relements.length) {
+            for (var i = 0; i < length; i++) {
+                if (elements[i].valueOf() !== relements[i].valueOf()) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    } else {
+        return false;
+    }
+};
+
diff --git a/proton-c/bindings/javascript/data-binary.js b/proton-c/bindings/javascript/data-binary.js
new file mode 100644
index 0000000..27bac59
--- /dev/null
+++ b/proton-c/bindings/javascript/data-binary.js
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.Binary                            */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Create a proton.Data.Binary. This constructor takes one or two parameters.
+ * The first parameter may serve different purposes depending on its type;
+ * If value is a number then it represents the size of the Binary data buffer,
+ * if it is a string then we copy the string to the buffer, if it is an Array
+ * or a TypedArray then we copy the data to the buffer. The optional second
+ * parameter is a pointer to the data in an internal data store. If start is
+ * not specified then the number of bytes specified in the first parameter
+ * will be allocated in the internal data store and start will point to the
+ * start of that block of data.
+ * @classdesc
+ * This class represents an AMQP Binary type. This class allows us to create and
+ * use raw binary data and map it efficiently between JavaScript client code and
+ * the underlying implementation, where all data is managed on a "virtual heap".
+ * <p>
+ * Client applications should generally not have to care about memory management
+ * as, for most common use cases, client applications would "transfer ownership"
+ * to a "container" which would then "own" the underlying data and free the data
+ * held by the {@link proton.Data.Binary}.
+ * <p>
+ * As an example one common use-case would be where client application creates a
+ * {@link proton.Data.Binary} specifying the required size. It would usually then
+ * call getBuffer() to access the underlying Uint8Array. At this point the client
+ * "owns" the data and so would have to call free() if it did nothing more with
+ * the Binary, however when {@link proton.Data.putBINARY} is called the ownership
+ * of the raw data on the virtual heap transfers from the Binary to the Data and
+ * the client no longer needs to call free() itself. In this case the putBINARY()
+ * call transfers ownership and can then safely call free() on the Binary.
+ * <p>
+ * Conversely a common use-case when receiving data is where a Binary may be
+ * created by {@link proton.Data#getBINARY}. In this case the Binary is simply a
+ * "view" onto the bytes owned by the Data instance. A client application can
+ * safely access the bytes from the view, but if it wishes to use the bytes beyond
+ * the scope of the Data instance (e.g. after the next {@link proton.Messenger#get}
+ * call then the client must explicitly *copy* the bytes into a new buffer, for
+ * example via copyBuffer().
+ * <p>
+ * Most of the {@link proton.Data} methods that take {@link proton.Data.Binary}
+ * as a parameter "consume" the underlying data and take responsibility for
+ * freeing it from the heap e.g. {@link proton.Data#putBINARY}, {@link proton.Data#decode}.
+ * For the methods that return a {@link proton.Data.Binary} the call to
+ * {@link proton.Data#getBINARY}, which is the most common case, returns a Binary
+ * that has a "view" of the underlying data that is actually owned by the Data
+ * instance and thus doesn't need to be explicitly freed on the Binary. The call
+ * to {@link proton.Data#encode} however returns a Binary that represents a *copy*
+ * of the underlying data, in this case (like a client calling new proton.Data.Binary)
+ * the client takes responsibility for freeing the data, unless of course it is
+ * subsequently passed to a method that will consume the data (putBINARY/decode).
+ * @constructor proton.Data.Binary
+ * @param {(number|string|Array|TypedArray)} value If value is a number then it 
+ *        represents the size of the Binary data buffer, if it is a string then
+ *        we copy the string to the buffer, if it is an Array or a TypedArray
+ *        then we copy the data to the buffer. N.B. although convenient do bear
+ *        in mind that using a mechanism other than constructing with a simple
+ *        size will result in some form of additional data copy.
+ * @param {number} start an optional pointer to the start of the Binary data buffer.
+ */
+Data['Binary'] = function(value, start) { // Data.Binary Constructor.
+    /**
+     * If the start pointer is specified then the underlying binary data is owned
+     * by another object, so we set the call to free to be a null function. If
+     * the start pointer is not passed then we allocate storage of the specified
+     * size on the emscripten heap and set the call to free to free the data from
+     * the emscripten heap.
+     */
+    var size = value;
+    if (start) {
+        this['free'] = function() {};
+    } else { // Create Binary from Array, ArrayBuffer or TypedArray.
+        var hasArrayBuffer = (typeof ArrayBuffer === 'function');
+        if (Data.isArray(value) ||
+            (hasArrayBuffer && value instanceof ArrayBuffer) || 
+            (value.buffer && hasArrayBuffer && value.buffer instanceof ArrayBuffer)) {
+            value = new Uint8Array(value);
+            size = value.length;
+            start = _malloc(size); // Allocate storage from emscripten heap.
+            Module['HEAPU8'].set(value, start); // Copy the data to the emscripten heap.
+        } else if (Data.isString(value)) { // Create Binary from native string
+            value = unescape(encodeURIComponent(value)); // Create a C-like UTF representation.
+            size = value.length;
+            start = _malloc(size); // Allocate storage from emscripten heap.
+            for (var i = 0; i < size; i++) {
+                setValue(start + i, value.charCodeAt(i), 'i8', 1);
+            }
+        } else { // Create unpopulated Binary of specified size.
+            // If the type is not a number by this point then an unrecognised data
+            // type has been passed so we create a zero length Binary.
+            size = Data.isNumber(size) ? size : 0;
+            start = _malloc(size); // Allocate storage from emscripten heap.
+        }
+        this['free'] = function() {
+            _free(this.start);
+            this.size = 0;
+            this.start = 0;
+            // Set free to a null function to prevent possibility of a "double free".
+            this['free'] = function() {};
+        };
+    }
+
+    this.size = size;
+    this.start = start;
+};
+
+/**
+ * Get a Uint8Array view of the data. N.B. this is just a *view* of the data,
+ * which will go out of scope on the next call to {@link proton.Messenger.get}. If
+ * a client wants to retain the data then copy should be used to explicitly
+ * create a copy of the data which the client then owns to do with as it wishes.
+ * @method getBuffer
+ * @returns {Uint8Array} a new Uint8Array view of the data.
+ * @memberof! proton.Data.Binary#
+ */
+Data['Binary'].prototype['getBuffer'] = function() {
+    return new Uint8Array(HEAPU8.buffer, this.start, this.size);
+};
+
+/**
+ * Explicitly create a *copy* of the Binary, copying the underlying binary data too.
+ * @method copy
+ * @param {number} offset an optional offset into the underlying buffer from
+ *        where we want to copy the data, default is zero.
+ * @param {number} n an optional number of bytes to copy, default is this.size - offset.
+ * @returns {proton.Data.Binary} a new {@link proton.Data.Binary} created by copying the underlying binary data.
+ * @memberof! proton.Data.Binary#
+ */
+Data['Binary'].prototype['copy'] = function(offset, n) {
+    offset = offset | 0;
+    n = n ? n : (this.size - offset);
+
+    if (offset >= this.size) {
+        offset = 0;
+        n = 0;
+    } else if ((offset + n) > this.size) {
+        n = this.size - offset; // Clamp length
+    }
+
+    var start = _malloc(n); // Allocate storage from emscripten heap.
+    _memcpy(start, this.start + offset, n); // Copy the raw data to new buffer.
+
+    return new Data['Binary'](n, start);
+};
+
+/**
+ * Converts the {@link proton.Data.Binary} to a string. This is clearly most
+ * useful when the binary data is actually a binary representation of a string
+ * such as a C style ASCII string.
+ * @method toString
+ * @memberof! proton.Data.Binary#
+ * @returns {string} the String form of a {@link proton.Data.Binary}.
+ */
+Data['Binary'].prototype.toString = Data['Binary'].prototype.valueOf = function() {
+    // Create a native JavaScript String from the start/size information.
+    return Pointer_stringify(this.start, this.size);
+};
+
diff --git a/proton-c/bindings/javascript/data-described.js b/proton-c/bindings/javascript/data-described.js
new file mode 100644
index 0000000..e1f9d84
--- /dev/null
+++ b/proton-c/bindings/javascript/data-described.js
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.Described                         */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Create a proton.Data.Described.
+ * @classdesc
+ * This class represents an AMQP Described.
+ * @constructor proton.Data.Described
+ * @param {object} value the value of the described type.
+ * @param {string} descriptor an optional string describing the type.
+ * @property {object} value the actual value of the described type.
+ * @property {string} descriptor a string describing the type.
+ */
+Data['Described'] = function(value, descriptor) { // Data.Described Constructor.
+    this['value'] = value;
+    this['descriptor'] = descriptor;
+};
+
+/**
+ * @method toString
+ * @memberof! proton.Data.Described#
+ * @returns {string} the String form of a {@link proton.Data.Described}.
+ */
+Data['Described'].prototype.toString = function() {
+    return 'Described(' + this['value'] + ', ' + this['descriptor'] + ')';
+};
+
+/**
+ * @method valueOf
+ * @memberof! proton.Data.Described#
+ * @returns {object} the value of the {@link proton.Data.Described}.
+ */
+Data['Described'].prototype.valueOf = function() {
+    return this['value'];
+};
+
+/**
+ * Compare two instances of proton.Data.Described for equality.
+ * @method equals
+ * @memberof! proton.Data.Described#
+ * @param {proton.Data.Described} rhs the instance we wish to compare this instance with.
+ * @returns {boolean} true iff the two compared instances are equal.
+ */
+Data['Described'].prototype['equals'] = function(rhs) {
+    if (rhs instanceof Data['Described']) {
+        return ((this['descriptor'] === rhs['descriptor']) && (this['value'] === rhs['value']));
+    } else {
+        return false;
+    }
+};
+
diff --git a/proton-c/bindings/javascript/data-long.js b/proton-c/bindings/javascript/data-long.js
new file mode 100644
index 0000000..38fb6c8
--- /dev/null
+++ b/proton-c/bindings/javascript/data-long.js
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.Long                              */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Create a proton.Data.Long.
+ * @classdesc
+ * This class represents a 64 bit Integer value. It is used primarily to pass and
+ * return 64 bit Integer values to and from the emscripten compiled proton-c library.
+ * This class is needed because JavaScript cannot natively represent 64 bit
+ * Integers with sufficient accuracy.
+ * @constructor proton.Data.Long
+ * @param {number} low the least significant word.
+ * @param {number} high the most significant word.
+ */
+// Use dot notation as it is a "protected" inner class not exported from the closure.
+Data.Long = function(low, high) { // Data.Long Constructor.
+    this.low  = low  | 0;  // force into 32 signed bits.
+    this.high = high | 0;  // force into 32 signed bits.
+};
+
+// proton.Data.Long constants.
+Data.Long.TWO_PWR_16_DBL_ = 1 << 16;
+Data.Long.TWO_PWR_32_DBL_ = Data.Long.TWO_PWR_16_DBL_ * Data.Long.TWO_PWR_16_DBL_;
+Data.Long.TWO_PWR_64_DBL_ = Data.Long.TWO_PWR_32_DBL_ * Data.Long.TWO_PWR_32_DBL_;
+Data.Long.TWO_PWR_63_DBL_ = Data.Long.TWO_PWR_64_DBL_ / 2;
+Data.Long.MAX_VALUE = new Data.Long(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
+Data.Long.MIN_VALUE = new Data.Long(0, 0x80000000 | 0);
+Data.Long.ZERO = new Data.Long(0, 0);
+Data.Long.ONE  = new Data.Long(1, 0);
+
+/**
+ * @method fromNumber
+ * @memberof! proton.Data.Long#
+ * @returns {proton.Data.Long} an instance of {@link proton.Data.Long} created
+ *          using a native JavaScript number.
+ */
+Data.Long.fromNumber = function(value) {
+    if (isNaN(value) || !isFinite(value)) {
+        return Data.Long.ZERO;
+    } else if (value <= -Data.Long.TWO_PWR_63_DBL_) {
+        return Data.Long.MIN_VALUE;
+    } else if (value + 1 >= Data.Long.TWO_PWR_63_DBL_) {
+        return Data.Long.MAX_VALUE;
+    } else if (value < 0) {
+        return Data.Long.fromNumber(-value).negate();
+    } else {
+      return new Data.Long(
+          (value % Data.Long.TWO_PWR_32_DBL_) | 0,
+          (value / Data.Long.TWO_PWR_32_DBL_) | 0);
+    }
+};
+
+/**
+ * Return the twos complement of this instance.
+ * @method negate
+ * @memberof! proton.Data.Long#
+ * @returns {proton.Data.Long} the twos complement of this instance.
+ */
+Data.Long.prototype.negate = function() {
+    if (this.equals(Data.Long.MIN_VALUE)) {
+        return Data.Long.MIN_VALUE;
+    } else {
+        return this.not().add(Data.Long.ONE);
+    }
+};
+
+/**
+ * Add two instances of {@link proton.Data.Long}.
+ * @method add
+ * @memberof! proton.Data.Long#
+ * @param {proton.Data.Long} rhs the instance we wish to add to this instance.
+ * @returns {proton.Data.Long} the sum of this value and the rhs.
+ */
+Data.Long.prototype.add = function(rhs) {
+    // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
+
+    var a48 = this.high >>> 16;
+    var a32 = this.high & 0xFFFF;
+    var a16 = this.low >>> 16;
+    var a00 = this.low & 0xFFFF;
+
+    var b48 = rhs.high >>> 16;
+    var b32 = rhs.high & 0xFFFF;
+    var b16 = rhs.low >>> 16;
+    var b00 = rhs.low & 0xFFFF;
+
+    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+    c00 += a00 + b00;
+    c16 += c00 >>> 16;
+    c00 &= 0xFFFF;
+    c16 += a16 + b16;
+    c32 += c16 >>> 16;
+    c16 &= 0xFFFF;
+    c32 += a32 + b32;
+    c48 += c32 >>> 16;
+    c32 &= 0xFFFF;
+    c48 += a48 + b48;
+    c48 &= 0xFFFF;
+    return new Data.Long((c16 << 16) | c00, (c48 << 16) | c32);
+};
+
+/**
+ * Return the complement of this instance.
+ * @method not
+ * @memberof! proton.Data.Long#
+ * @returns {proton.Data.Long} the complement of this instance.
+ */
+Data.Long.prototype.not = function() {
+    return new Data.Long(~this.low, ~this.high);
+};
+
+/**
+ * Compare two instances of {@link proton.Data.Long} for equality.
+ * @method equals
+ * @memberof! proton.Data.Long#
+ * @param {proton.Data.Long} rhs the instance we wish to compare this instance with.
+ * @returns {boolean} true iff the two compared instances are equal.
+ */
+Data.Long.prototype.equals = function(other) {
+    return (this.high == other.high) && (this.low == other.low);
+};
+
+/**
+ * @method getHighBits
+ * @memberof! proton.Data.Long#
+ * @returns {number} the most significant word of a {@link proton.Data.Long}.
+ */
+Data.Long.prototype.getHighBits = function() {
+    return this.high;
+};
+
+/**
+ * @method getLowBits
+ * @memberof! proton.Data.Long#
+ * @returns {number} the least significant word of a {@link proton.Data.Long}.
+ */
+Data.Long.prototype.getLowBits = function() {
+    return this.low;
+};
+
+/**
+ * @method getLowBitsUnsigned
+ * @memberof! proton.Data.Long#
+ * @returns {number} the least significant word of a {@link proton.Data.Long}
+ *          as an unsigned value.
+ */
+Data.Long.prototype.getLowBitsUnsigned = function() {
+    return (this.low >= 0) ? this.low : Data.Long.TWO_PWR_32_DBL_ + this.low;
+};
+
+/**
+ * @method toNumber
+ * @memberof! proton.Data.Long#
+ * @returns {number} a native JavaScript number (with possible loss of precision).
+ */
+Data.Long.prototype.toNumber = function() {
+    return (this.high * Data.Long.TWO_PWR_32_DBL_) + this.getLowBitsUnsigned();
+};
+
+/**
+ * @method toString
+ * @memberof! proton.Data.Long#
+ * @returns {string} the String form of a {@link proton.Data.Long}.
+ */
+Data.Long.prototype.toString = function() {
+    return this.high + ':' + this.getLowBitsUnsigned();
+};
+
diff --git a/proton-c/bindings/javascript/data-symbol.js b/proton-c/bindings/javascript/data-symbol.js
new file mode 100644
index 0000000..c742acb
--- /dev/null
+++ b/proton-c/bindings/javascript/data-symbol.js
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.Symbol                            */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Create a proton.Data.Symbol.
+ * @classdesc
+ * This class represents an AMQP Symbol. This class is necessary primarily as a
+ * way to enable us to distinguish between a native String and a Symbol in the
+ * JavaScript type system.
+ * @constructor proton.Data.Symbol
+ * @param {string} s a symbol.
+ */
+Data['Symbol'] = function(s) { // Data.Symbol Constructor.
+    this.value = s;
+};
+
+/**
+ * @method toString
+ * @memberof! proton.Data.Symbol#
+ * @returns {string} the String form of a {@link proton.Data.Symbol}.
+ */
+Data['Symbol'].prototype.toString = Data['Symbol'].prototype.valueOf = function() {
+    return this.value;
+};
+
+/**
+ * Compare two instances of proton.Data.Symbol for equality.
+ * @method equals
+ * @memberof! proton.Data.Symbol#
+ * @param {proton.Data.Symbol} rhs the instance we wish to compare this instance with.
+ * @returns {boolean} true iff the two compared instances are equal.
+ */
+Data['Symbol'].prototype['equals'] = function(rhs) {
+    return this.toString() === rhs.toString();
+};
+
diff --git a/proton-c/bindings/javascript/data-typed-number.js b/proton-c/bindings/javascript/data-typed-number.js
new file mode 100644
index 0000000..034d4ec
--- /dev/null
+++ b/proton-c/bindings/javascript/data-typed-number.js
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.TypedNumber                       */
+/*                                                                           */
+/*****************************************************************************/
+
+// ---------------------- JavaScript Number Extensions ------------------------ 
+
+Number.prototype['ubyte'] = function() {
+    return new Data.TypedNumber('UBYTE', this);
+};
+
+Number.prototype['byte'] = function() {
+    return new Data.TypedNumber('BYTE', this);
+};
+
+Number.prototype['ushort'] = function() {
+    return new Data.TypedNumber('USHORT', this);
+};
+
+Number.prototype['short'] = function() {
+    return new Data.TypedNumber('SHORT', this);
+};
+
+Number.prototype['uint'] = function() {
+    return new Data.TypedNumber('UINT', this);
+};
+
+Number.prototype['int'] = function() {
+    return new Data.TypedNumber('INT', this);
+};
+
+Number.prototype['ulong'] = function() {
+    return new Data.TypedNumber('ULONG', this);
+};
+
+Number.prototype['long'] = function() {
+    return new Data.TypedNumber('LONG', this);
+};
+
+Number.prototype['float'] = function() {
+    return new Data.TypedNumber('FLOAT', this);
+};
+
+Number.prototype['double'] = function() {
+    return new Data.TypedNumber('DOUBLE', this);
+};
+
+Number.prototype['char'] = function() {
+    return new Data.TypedNumber('CHAR', this);
+};
+
+String.prototype['char'] = function() {
+    return new Data.TypedNumber('CHAR', this.charCodeAt(0));
+};
+
+// ------------------------- proton.Data.TypedNumber -------------------------- 
+/**
+ * Create a proton.Data.TypedNumber.
+ * @classdesc
+ * This class is a simple wrapper class that allows a "type" to be recorded for
+ * a number. The idea is that the JavaScript Number class is extended with extra
+ * methods to allow numbers to be "modified" to TypedNumbers, so for example
+ * 1.0.float() would modify 1.0 by returning a TypedNumber with type = FLOAT
+ * and value = 1. The strings used for type correspond to the names of the Data
+ * put* methods e.g. UBYTE, BYTE, USHORT, SHORT, UINT, INT, ULONG, LONG, FLOAT,
+ * DOUBLE, CHAR so that the correct method to call can be derived from the type.
+ * @constructor proton.Data.TypedNumber
+ * @param {(string|number)} type the type of the Number either as a string or number.
+ *        Stored internally as a string corresponding to one of the TypeNames.
+ * @param {number} value the value of the Number.
+ */
+// Use dot notation as it is a "protected" inner class not exported from the closure.
+Data.TypedNumber = function(type, value) { // Data.TypedNumber Constructor.
+    this.type  = (typeof type === 'number') ? Data['TypeNames'][type] : type;
+    this.value = value;
+};
+
+/**
+ * @method toString
+ * @memberof! proton.Data.TypedNumber#
+ * @returns {string} the String form of a {@link proton.Data.TypedNumber}.
+ */
+Data.TypedNumber.prototype.toString = Data.TypedNumber.prototype.valueOf = function() {
+    return +this.value;
+};
+
+
diff --git a/proton-c/bindings/javascript/data-uuid.js b/proton-c/bindings/javascript/data-uuid.js
new file mode 100644
index 0000000..4fee84a
--- /dev/null
+++ b/proton-c/bindings/javascript/data-uuid.js
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                             proton.Data.Uuid                              */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Create a proton.Data.Uuid which is a type 4 UUID.
+ * @classdesc
+ * This class represents a type 4 UUID, wich may use crypto libraries to generate
+ * the UUID if supported by the platform (e.g. node.js or a modern browser)
+ * @constructor proton.Data.Uuid
+ * @param {number|Array|string} u a UUID. If null a type 4 UUID is generated wich may use crypto if
+ *        supported by the platform. If u is an emscripten "pointer" we copy the
+ *        data from that. If u is a JavaScript Array we use it as-is. If u is a
+ *        String then we try to parse that as a UUID.
+ * @property {Array} uuid is the compact array form of the UUID.
+ */
+Data['Uuid'] = function(u) { // Data.Uuid Constructor.
+    // Helper to copy from emscriptem allocated storage into JavaScript Array.
+    function _p2a(p) {
+        var uuid = new Array(16);
+        for (var i = 0; i < 16; i++) {
+            uuid[i] = getValue(p + i, 'i8') & 0xFF; // & 0xFF converts to unsigned.
+        }
+        return uuid;
+    };
+
+    if (!u) { // Generate UUID using emscriptem's uuid_generate implementation.
+        var sp = Runtime.stackSave();
+        var p = allocate(16, 'i8', ALLOC_STACK); // Create temporary pointer storage.
+        _uuid_generate(p);      // Generate UUID into allocated pointer.
+        this['uuid'] = _p2a(p); // Copy from allocated storage into JavaScript Array.
+        Runtime.stackRestore(sp);
+    } else if (Data.isNumber(u)) { // Use pointer that has been passed in.
+        this['uuid'] = _p2a(u);    // Copy from allocated storage into JavaScript Array.
+    } else if (Data.isArray(u)) { // Use array that has been passed in.
+        this['uuid'] = u; // Just use the JavaScript Array.
+    } else if (Data.isString(u)) { // Parse String form UUID.
+        if (u.length === 36) {
+            var i = 0;
+            var uuid = new Array(16);
+            u.toLowerCase().replace(/[0-9a-f]{2}/g, function(byte) {
+                if (i < 16) {
+                    uuid[i++] = parseInt(byte, 16);
+                }
+            });
+            this['uuid'] = uuid;
+        }
+    }
+    this.string = null;
+};
+
+/**
+ * Returns the string representation of the proton.Data.Uuid.
+ * @method toString
+ * @memberof! proton.Data.Uuid#
+ * @returns {string} the String
+ *          /[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/
+ *          form of a {@link proton.Data.Uuid}.
+ */
+Data['Uuid'].prototype.toString = Data['Uuid'].prototype.valueOf = function() {
+    if (!this.string) { // Check if we've cached the string version.
+        var i = 0;
+        var uu = this['uuid'];
+        var uuid = 'xxxx-xx-xx-xx-xxxxxx'.replace(/[x]/g, function(c) {
+            var r = uu[i].toString(16);
+            r = (r.length === 1) ? '0' + r : r; // Zero pad single digit hex values
+            i++;
+            return r;
+        });
+        this.string = uuid;
+    }
+    return this.string;
+};
+
+/**
+ * Compare two instances of proton.Data.Uuid for equality.
+ * @method equals
+ * @memberof! proton.Data.Uuid#
+ * @param {proton.Data.Uuid} rhs the instance we wish to compare this instance with.
+ * @returns {boolean} true iff the two compared instances are equal.
+ */
+Data['Uuid'].prototype['equals'] = function(rhs) {
+    return this.toString() === rhs.toString();
+};
+
diff --git a/proton-c/bindings/javascript/data.js b/proton-c/bindings/javascript/data.js
new file mode 100644
index 0000000..018c5fb
--- /dev/null
+++ b/proton-c/bindings/javascript/data.js
@@ -0,0 +1,1577 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                    Data                                   */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.Data instance.
+ * @classdesc
+ * The Data class provides an interface for decoding, extracting, creating, and
+ * encoding arbitrary AMQP data. A Data object contains a tree of AMQP values.
+ * Leaf nodes in this tree correspond to scalars in the AMQP type system such as
+ * ints<INT> or strings<STRING>. Non-leaf nodes in this tree correspond to compound
+ * values in the AMQP type system such as lists<LIST>, maps<MAP>, arrays<ARRAY>,
+ * or described values<DESCRIBED>. The root node of the tree is the Data object
+ * itself and can have an arbitrary number of children.
+ * <p>
+ * A Data object maintains the notion of the current sibling node and a current
+ * parent node. Siblings are ordered within their parent. Values are accessed
+ * and/or added by using the next, prev, enter, and exit methods to navigate to
+ * the desired location in the tree and using the supplied variety of put* and
+ * get* methods to access or add a value of the desired type.
+ * <p>
+ * The put* methods will always add a value after the current node in the tree.
+ * If the current node has a next sibling the put* method will overwrite the value
+ * on this node. If there is no current node or the current node has no next
+ * sibling then one will be added. The put* methods always set the added/modified
+ * node to the current node. The get* methods read the value of the current node
+ * and do not change which node is current.
+ * @constructor proton.Data
+ * @param {number} data an optional pointer to a pn_data_t instance. If supplied
+ *        the underlying data is "owned" by another object (for example a Message)
+ *        and that object is assumed to be responsible for freeing the data if
+ *        necessary. If no data is supplied then the Data is stand-alone and the
+ *        client application is responsible for freeing the underlying data via
+ *        a call to free().
+ * @param {boolean} decodeBinaryAsString if set decode any AMQP Binary payload
+ *        objects as strings. This can be useful as the data in Binary objects
+ *        will be overwritten with subsequent calls to get, so they must be
+ *        explicitly copied. Needless to say it is only safe to set this flag if
+ *        you know that the data you are dealing with is actually a string, for
+ *        example C/C++ applications often seem to encode strings as AMQP binary,
+ *        a common cause of interoperability problems.
+ */
+Module['Data'] = function(data, decodeBinaryAsString) { // Data Constructor.
+    if (!data) {
+        this._data = _pn_data(16); // Default capacity is 16
+        this['free'] = function() {
+            _pn_data_free(this._data);
+            // Set free to a null function to prevent possibility of a "double free".
+            this['free'] = function() {};
+        };
+    } else {
+        this._data = data;
+        this['free'] = function() {};
+    }
+    this._decodeBinaryAsString = decodeBinaryAsString;
+};
+
+// Expose constructor as package scope variable to make internal calls less verbose.
+var Data = Module['Data'];
+
+// Expose prototype as a variable to make method declarations less verbose.
+var _Data_ = Data.prototype;
+
+// ************************** Class properties ********************************
+
+Data['NULL']       = 1;
+Data['BOOL']       = 2;
+Data['UBYTE']      = 3;
+Data['BYTE']       = 4;
+Data['USHORT']     = 5;
+Data['SHORT']      = 6;
+Data['UINT']       = 7;
+Data['INT']        = 8;
+Data['CHAR']       = 9;
+Data['ULONG']      = 10;
+Data['LONG']       = 11;
+Data['TIMESTAMP']  = 12;
+Data['FLOAT']      = 13;
+Data['DOUBLE']     = 14;
+Data['DECIMAL32']  = 15;
+Data['DECIMAL64']  = 16;
+Data['DECIMAL128'] = 17;
+Data['UUID']       = 18;
+Data['BINARY']     = 19;
+Data['STRING']     = 20;
+Data['SYMBOL']     = 21;
+Data['DESCRIBED']  = 22;
+Data['ARRAY']      = 23;
+Data['LIST']       = 24;
+Data['MAP']        = 25;
+
+/**
+ * Look-up table mapping proton-c types to the accessor method used to
+ * deserialise the type. N.B. this is a simple Array and not a map because the
+ * types that we get back from pn_data_type are integers from the pn_type_t enum.
+ * @property {Array<String>} TypeNames ['NULL', 'NULL', 'BOOL', 'UBYTE', 'BYTE',
+ * 'USHORT', 'SHORT', 'UINT', 'INT', 'CHAR', 'ULONG', 'LONG', 'TIMESTAMP',
+ * 'FLOAT', 'DOUBLE', 'DECIMAL32', 'DECIMAL64', 'DECIMAL128', 'UUID',
+ * 'BINARY', 'STRING', 'SYMBOL', 'DESCRIBED', 'ARRAY', 'LIST', 'MAP']
+ * @memberof! proton.Data
+ */
+Data['TypeNames'] = [
+    'NULL',       // 0
+    'NULL',       // PN_NULL       = 1
+    'BOOL',       // PN_BOOL       = 2
+    'UBYTE',      // PN_UBYTE      = 3
+    'BYTE',       // PN_BYTE       = 4
+    'USHORT',     // PN_USHORT     = 5
+    'SHORT',      // PN_SHORT      = 6
+    'UINT',       // PN_UINT       = 7
+    'INT',        // PN_INT        = 8
+    'CHAR',       // PN_CHAR       = 9
+    'ULONG',      // PN_ULONG      = 10
+    'LONG',       // PN_LONG       = 11
+    'TIMESTAMP',  // PN_TIMESTAMP  = 12
+    'FLOAT',      // PN_FLOAT      = 13
+    'DOUBLE',     // PN_DOUBLE     = 14
+    'DECIMAL32',  // PN_DECIMAL32  = 15
+    'DECIMAL64',  // PN_DECIMAL64  = 16
+    'DECIMAL128', // PN_DECIMAL128 = 17
+    'UUID',       // PN_UUID       = 18
+    'BINARY',     // PN_BINARY     = 19
+    'STRING',     // PN_STRING     = 20
+    'SYMBOL',     // PN_SYMBOL     = 21
+    'DESCRIBED',  // PN_DESCRIBED  = 22
+    'ARRAY',      // PN_ARRAY      = 23
+    'LIST',       // PN_LIST       = 24
+    'MAP'         // PN_MAP        = 25
+];
+
+// *************************** Class methods **********************************
+
+/**
+ * Test if a given Object is a JavaScript Array.
+ * @method isArray
+ * @memberof! proton.Data
+ * @param {object} o the Object that we wish to test.
+ * @returns {boolean} true iff the Object is a JavaScript Array.
+ */
+Data.isArray = Array.isArray || function(o) {
+    return Object.prototype.toString.call(o) === '[object Array]';
+};
+
+/**
+ * Test if a given Object is a JavaScript Number.
+ * @method isNumber
+ * @memberof! proton.Data
+ * @param {object} o the Object that we wish to test.
+ * @returns {boolean} true iff the Object is a JavaScript Number.
+ */
+Data.isNumber = function(o) {
+    return typeof o === 'number' || 
+          (typeof o === 'object' && Object.prototype.toString.call(o) === '[object Number]');
+};
+
+/**
+ * Test if a given Object is a JavaScript String.
+ * @method isString
+ * @memberof! proton.Data
+ * @param {object} o the Object that we wish to test.
+ * @returns {boolean} true iff the Object is a JavaScript String.
+ */
+Data.isString = function(o) {
+    return typeof o === 'string' ||
+          (typeof o === 'object' && Object.prototype.toString.call(o) === '[object String]');
+};
+
+/**
+ * Test if a given Object is a JavaScript Boolean.
+ * @method isBoolean
+ * @memberof! proton.Data
+ * @param {object} o the Object that we wish to test.
+ * @returns {boolean} true iff the Object is a JavaScript Boolean.
+ */
+Data.isBoolean = function(o) {
+    return typeof o === 'boolean' ||
+          (typeof o === 'object' && Object.prototype.toString.call(o) === '[object Boolean]');
+};
+
+
+// ************************* Protected methods ********************************
+
+// We use the dot notation rather than associative array form for protected
+// methods so they are visible to this "package", but the Closure compiler will
+// minify and obfuscate names, effectively making a defacto "protected" method.
+
+/**
+ * This helper method checks the supplied error code, converts it into an
+ * exception and throws the exception. This method will try to use the message
+ * populated in pn_data_error(), if present, but if not it will fall
+ * back to using the basic error code rendering from pn_code().
+ * @param code the error code to check.
+ */
+_Data_._check = function(code) {
+    if (code < 0) {
+        var errno = this['getErrno']();
+        var message = errno ? this['getError']() : Pointer_stringify(_pn_code(code));
+
+        throw new Module['DataError'](message);
+    } else {
+        return code;
+    }
+};
+
+
+// *************************** Public methods *********************************
+
+/**
+ * @method getErrno
+ * @memberof! proton.Data#
+ * @returns {number} the most recent error message code.
+ */
+_Data_['getErrno'] = function() {
+    return _pn_data_errno(this._data);
+};
+
+/**
+ * @method getError
+ * @memberof! proton.Data#
+ * @returns {string} the most recent error message as a String.
+ */
+_Data_['getError'] = function() {
+    return Pointer_stringify(_pn_error_text(_pn_data_error(this._data)));
+};
+
+/**
+ * Clears the data object.
+ * @method clear
+ * @memberof! proton.Data#
+ */
+_Data_['clear'] = function() {
+    _pn_data_clear(this._data);
+};
+
+/**
+ * Clears current node and sets the parent to the root node.  Clearing the current
+ * node sets it _before_ the first node, calling next() will advance to the first node.
+ * @method rewind
+ * @memberof! proton.Data#
+ */
+_Data_['rewind'] = function() {
+    _pn_data_rewind(this._data);
+};
+
+/**
+ * Advances the current node to its next sibling and returns its type. If there
+ * is no next sibling the current node remains unchanged and null is returned.
+ * @method next
+ * @memberof! proton.Data#
+ * @returns {number} the type of the next sibling or null.
+ */
+_Data_['next'] = function() {
+    var found = _pn_data_next(this._data);
+    if (found) {
+        return this.type();
+    } else {
+        return null;
+    }
+};
+
+/**
+ * Advances the current node to its previous sibling and returns its type. If there
+ * is no previous sibling the current node remains unchanged and null is returned.
+ * @method prev
+ * @memberof! proton.Data#
+ * @returns {number} the type of the previous sibling or null.
+ */
+_Data_['prev'] = function() {
+    var found = _pn_data_prev(this._data);
+    if (found) {
+        return this.type();
+    } else {
+        return null;  
+    }
+};
+
+/**
+ * Sets the parent node to the current node and clears the current node. Clearing
+ * the current node sets it _before_ the first child, next() advances to the first child.
+ * @method enter
+ * @memberof! proton.Data#
+ */
+_Data_['enter'] = function() {
+    return (_pn_data_enter(this._data) > 0);
+};
+
+/**
+ * Sets the current node to the parent node and the parent node to its own parent.
+ * @method exit
+ * @memberof! proton.Data#
+ */
+_Data_['exit'] = function() {
+    return (_pn_data_exit(this._data) > 0);
+};
+
+/**
+ * Look up a value by name. N.B. Need to use getObject() to retrieve the actual
+ * value after lookup suceeds.
+ * @method lookup
+ * @memberof! proton.Data#
+ * @param {string} name the name of the property to look up.
+ * @returns {boolean} true iff the lookup succeeded.
+ */
+_Data_['lookup'] = function(name) {
+    var sp = Runtime.stackSave();
+    var lookup = _pn_data_lookup(this._data, allocate(intArrayFromString(name), 'i8', ALLOC_STACK));
+    Runtime.stackRestore(sp);
+    return (lookup > 0);
+};
+
+// TODO document - not quite sure what these are for?
+_Data_['narrow'] = function() {
+    _pn_data_narrow(this._data);
+};
+
+_Data_['widen'] = function() {
+    _pn_data_widen(this._data);
+};
+
+/**
+ * @method type
+ * @memberof! proton.Data#
+ * @returns {number} the type of the current node or null if the type is unknown.
+ */
+_Data_['type'] = function() {
+    var dtype = _pn_data_type(this._data);
+    if (dtype === -1) {
+        return null;
+    } else {
+        return dtype;
+    }
+};
+
+/**
+ * Return a Binary representation of the data encoded in AMQP format. N.B. the
+ * returned {@link proton.Data.Binary} "owns" the underlying raw data and is thus
+ * responsible for freeing it or passing it to a method that consumes a Binary
+ * such as {@link proton.Data.decode} or {@link proton.Data.putBINARY}.
+ * @method encode
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Binary} a representation of the data encoded in AMQP format.
+ */
+_Data_['encode'] = function() {
+    var size = 1024;
+    while (true) {
+        var bytes = _malloc(size); // Allocate storage from emscripten heap.
+        var cd = _pn_data_encode(this._data, bytes, size);
+
+        if (cd === Module['Error']['OVERFLOW']) {
+            _free(bytes);
+            size *= 2;
+        } else if (cd >= 0) {
+            return new Data['Binary'](cd, bytes);
+        } else {
+            _free(bytes);
+            this._check(cd);
+            return;
+        }
+    }
+};
+
+/**
+ * Decodes the first value from supplied Binary AMQP data and returns a new
+ * {@link proton.Data.Binary} containing the remainder of the data or null if
+ * all the supplied data has been consumed. N.B. this method "consumes" data
+ * from a {@link proton.Data.Binary} in other words it takes responsibility for
+ * the underlying data and frees the raw data from the Binary.
+ * @method decode
+ * @memberof! proton.Data#
+ * @param {proton.Data.Binary} encoded the AMQP encoded binary data.
+ * @returns {proton.Data.Binary} a Binary containing the remaining bytes or null
+ *          if all the data has been consumed.
+ */
+_Data_['decode'] = function(encoded) {
+    var start = encoded.start;
+    var size = encoded.size;
+    var consumed = this._check(_pn_data_decode(this._data, start, size));
+
+    size = size - consumed;
+    start = _malloc(size); // Allocate storage from emscripten heap.
+    _memcpy(start, encoded.start + consumed, size);
+
+    encoded['free'](); // Free the original Binary.
+    return size > 0 ? new Data['Binary'](size, start) : null;
+};
+
+/**
+ * Puts a list node. Elements may be filled by entering the list
+ * node and putting element values.
+ * <pre>
+ *  var data = new proton.Data();
+ *  data.putLISTNODE();
+ *  data.enter();
+ *  data.putINT(1);
+ *  data.putINT(2);
+ *  data.putINT(3);
+ *  data.exit();
+ * </pre>
+ * @method putLISTNODE
+ * @memberof! proton.Data#
+ */
+_Data_['putLISTNODE'] = function() {
+    this._check(_pn_data_put_list(this._data));
+};
+
+/**
+ * Puts a map node. Elements may be filled by entering the map node
+ * and putting alternating key value pairs.
+ * <pre>
+ *  var data = new proton.Data();
+ *  data.putMAPNODE();
+ *  data.enter();
+ *  data.putSTRING('key');
+ *  data.putSTRING('value');
+ *  data.exit();
+ * </pre>
+ * @method putMAPNODE
+ * @memberof! proton.Data#
+ */
+_Data_['putMAPNODE'] = function() {
+    this._check(_pn_data_put_map(this._data));
+};
+
+/**
+ * Puts an array node. Elements may be filled by entering the array node and
+ * putting the element values. The values must all be of the specified array
+ * element type. If an array is described then the first child value of the array
+ * is the descriptor and may be of any type.
+ * <pre>
+ *  var data = new proton.Data();
+ *  data.putARRAYNODE(false, proton.Data.INT);
+ *  data.enter();
+ *  data.putINT(1);
+ *  data.putINT(2);
+ *  data.putINT(3);
+ *  data.exit();
+ *
+ *  data.putARRAYNODE(true, proton.Data.DOUBLE);
+ *  data.enter();
+ *  data.putSYMBOL('array-descriptor');
+ *  data.putDOUBLE(1.1);
+ *  data.putDOUBLE(1.2);
+ *  data.putDOUBLE(1.3);
+ *  data.exit();
+ * </pre>
+ * @method putARRAYNODE
+ * @param {boolean} described specifies whether the array is described.
+ * @param {number} type the type of the array elements.
+ * @memberof! proton.Data#
+ */
+_Data_['putARRAYNODE'] = function(described, type) {
+    this._check(_pn_data_put_array(this._data, described, type));
+};
+
+/**
+ * Puts a described node. A described node has two children, the descriptor and
+ * value. These are specified by entering the node and putting the desired values.
+ * <pre>
+ *  var data = new proton.Data();
+ *  data.putDESCRIBEDNODE();
+ *  data.enter();
+ *  data.putSYMBOL('value-descriptor');
+ *  data.putSTRING('the value');
+ *  data.exit();
+ * </pre>
+ * @method putDESCRIBEDNODE
+ * @memberof! proton.Data#
+ */
+_Data_['putDESCRIBEDNODE'] = function() {
+    this._check(_pn_data_put_described(this._data));
+};
+
+/**
+ * Puts a null value.
+ * @method putNULL
+ * @memberof! proton.Data#
+ */
+_Data_['putNULL'] = function() {
+    this._check(_pn_data_put_null(this._data));
+};
+
+/**
+ * Puts a boolean value.
+ * @method putBOOL
+ * @memberof! proton.Data#
+ * @param {boolean} b a boolean value.
+ */
+_Data_['putBOOL'] = function(b) {
+    this._check(_pn_data_put_bool(this._data, b));
+};
+
+/**
+ * Puts a unsigned byte value.
+ * @method putUBYTE
+ * @memberof! proton.Data#
+ * @param {number} ub an integral value.
+ */
+_Data_['putUBYTE'] = function(ub) {
+    this._check(_pn_data_put_ubyte(this._data, ub));
+};
+
+/**
+ * Puts a signed byte value.
+ * @method putBYTE
+ * @memberof! proton.Data#
+ * @param {number} b an integral value.
+ */
+_Data_['putBYTE'] = function(b) {
+    this._check(_pn_data_put_byte(this._data, b));
+};
+
+/**
+ * Puts a unsigned short value.
+ * @method putUSHORT
+ * @memberof! proton.Data#
+ * @param {number} us an integral value.
+ */
+_Data_['putUSHORT'] = function(us) {
+    this._check(_pn_data_put_ushort(this._data, us));
+};
+
+/**
+ * Puts a signed short value.
+ * @method putSHORT
+ * @memberof! proton.Data#
+ * @param {number} s an integral value.
+ */
+_Data_['putSHORT'] = function(s) {
+    this._check(_pn_data_put_short(this._data, s));
+};
+
+/**
+ * Puts a unsigned integer value.
+ * @method putUINT
+ * @memberof! proton.Data#
+ * @param {number} ui an integral value.
+ */
+_Data_['putUINT'] = function(ui) {
+    this._check(_pn_data_put_uint(this._data, ui));
+};
+
+/**
+ * Puts a signed integer value.
+ * @method putINT
+ * @memberof! proton.Data#
+ * @param {number} i an integral value.
+ */
+_Data_['putINT'] = function(i) {
+    this._check(_pn_data_put_int(this._data, i));
+};
+
+/**
+ * Puts a signed char value.
+ * @method putCHAR
+ * @memberof! proton.Data#
+ * @param {(string|number)} c a single character expressed either as a string or a number.
+ */
+_Data_['putCHAR'] = function(c) {
+    c = Data.isString(c) ? c.charCodeAt(0) : c;
+    this._check(_pn_data_put_char(this._data, c));
+};
+
+/**
+ * Puts a unsigned long value. N.B. large values can suffer from a loss of
+ * precision as JavaScript numbers are restricted to 64 bit double values.
+ * @method putULONG
+ * @memberof! proton.Data#
+ * @param {number} ul an integral value.
+ */
+_Data_['putULONG'] = function(ul) {
+    // If the supplied number exceeds the range of Data.Long invert it before
+    // constructing the Data.Long.
+    ul = (ul >= Data.Long.TWO_PWR_63_DBL_) ? (ul = -(Data.Long.TWO_PWR_64_DBL_ - ul)) : ul;
+    var long = Data.Long.fromNumber(ul);
+    this._check(_pn_data_put_ulong(this._data, long.getLowBitsUnsigned(), long.getHighBits()));
+};
+
+/**
+ * Puts a signed long value. N.B. large values can suffer from a loss of
+ * precision as JavaScript numbers are restricted to 64 bit double values.
+ * @method putLONG
+ * @memberof! proton.Data#
+ * @param {number} i an integral value.
+ */
+_Data_['putLONG'] = function(l) {
+    var long = Data.Long.fromNumber(l);
+    this._check(_pn_data_put_long(this._data, long.getLowBitsUnsigned(), long.getHighBits()));
+};
+
+/**
+ * Puts a timestamp.
+ * @method putTIMESTAMP
+ * @memberof! proton.Data#
+ * @param {(number|Date)} d a Date value.
+ */
+_Data_['putTIMESTAMP'] = function(d) {
+    // Note that a timestamp is a 64 bit number so we have to use a proton.Data.Long.
+    var timestamp = Data.Long.fromNumber(d.valueOf());
+    this._check(_pn_data_put_timestamp(this._data, timestamp.getLowBitsUnsigned(), timestamp.getHighBits()));
+};
+
+/**
+ * Puts a float value. N.B. converting between floats and doubles is imprecise
+ * so the resulting value might not quite be what you expect.
+ * @method putFLOAT
+ * @memberof! proton.Data#
+ * @param {number} f a floating point value.
+ */
+_Data_['putFLOAT'] = function(f) {
+    this._check(_pn_data_put_float(this._data, f));
+};
+
+/**
+ * Puts a double value.
+ * @method putDOUBLE
+ * @memberof! proton.Data#
+ * @param {number} d a floating point value.
+ */
+_Data_['putDOUBLE'] = function(d) {
+    this._check(_pn_data_put_double(this._data, d));
+};
+
+/**
+ * Puts a decimal32 value.
+ * @method putDECIMAL32
+ * @memberof! proton.Data#
+ * @param {number} d a decimal32 value.
+ */
+_Data_['putDECIMAL32'] = function(d) {
+    this._check(_pn_data_put_decimal32(this._data, d));
+};
+
+/**
+ * Puts a decimal64 value.
+ * @method putDECIMAL64
+ * @memberof! proton.Data#
+ * @param {number} d a decimal64 value.
+ */
+_Data_['putDECIMAL64'] = function(d) {
+    this._check(_pn_data_put_decimal64(this._data, d));
+};
+
+/**
+ * Puts a decimal128 value.
+ * @method putDECIMAL128
+ * @memberof! proton.Data#
+ * @param {number} d a decimal128 value.
+ */
+_Data_['putDECIMAL128'] = function(d) {
+    this._check(_pn_data_put_decimal128(this._data, d));
+};
+
+/**
+ * Puts a UUID value.
+ * @method putUUID
+ * @memberof! proton.Data#
+ * @param {proton.Data.Uuid} u a uuid value
+ */
+_Data_['putUUID'] = function(u) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_data_put_uuid(this._data, allocate(u['uuid'], 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Puts a binary value consuming the underlying raw data in the process.
+ * @method putBINARY
+ * @memberof! proton.Data#
+ * @param {proton.Data.Binary} b a binary value.
+ */
+_Data_['putBINARY'] = function(b) {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_data_put_binary(data, pn_bytes(b.size, b.start));
+
+    // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
+    // the low-level code handles this *by pointer* so we first need to allocate
+    // 8 bytes storage for {size, start} on the emscripten stack and then we
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_bytes(bytes, b.size, b.start);
+
+    // The compiled pn_data_put_binary takes the pn_bytes_t by reference not value.
+    this._check(_pn_data_put_binary(this._data, bytes));
+
+    // After calling _pn_data_put_binary the underlying Data object "owns" the
+    // binary data, so we can call free on the proton.Data.Binary instance to
+    // release any storage it has acquired back to the emscripten heap.
+    b['free']();
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Puts a unicode string value.
+ * @method putSTRING
+ * @memberof! proton.Data#
+ * @param {string} s a unicode string value.
+ */
+_Data_['putSTRING'] = function(s) {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_data_put_string(data, pn_bytes(strlen(text), text));
+
+    // First create an array from the JavaScript String using the intArrayFromString
+    // helper function (from emscripten/src/preamble.js). We use this idiom in a
+    // few places but here we create array as a separate var as we need its length.
+    var array = intArrayFromString(s, true); // The true means don't add NULL.
+    // Allocate temporary storage for the array on the emscripten stack.
+    var str = allocate(array, 'i8', ALLOC_STACK);
+
+    // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
+    // the low-level code handles this *by pointer* so we first need to allocate
+    // 8 bytes storage for {size, start} on the emscripten stack and then we
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_bytes(bytes, array.length, str);
+
+    // The compiled pn_data_put_string takes the pn_bytes_t by reference not value.
+    this._check(_pn_data_put_string(this._data, bytes));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Puts a symbolic value. According to the AMQP 1.0 Specification Symbols are
+ * values from a constrained domain. Although the set of possible domains is
+ * open-ended, typically the both number and size of symbols in use for any
+ * given application will be small, e.g. small enough that it is reasonable to
+ * cache all the distinct values. Symbols are encoded as ASCII characters.
+ * @method putSYMBOL
+ * @memberof! proton.Data#
+ * @param {proton.Data.Symbol|string} s the symbol name.
+ */
+_Data_['putSYMBOL'] = function(s) {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_data_put_symbol(data, pn_bytes(strlen(text), text));
+
+    // First create an array from the JavaScript String using the intArrayFromString
+    // helper function (from emscripten/src/preamble.js). We use this idiom in a
+    // few places but here we create array as a separate var as we need its length.
+    var array = intArrayFromString(s, true); // The true means don't add NULL.
+    // Allocate temporary storage for the array on the emscripten stack.
+    var str = allocate(array, 'i8', ALLOC_STACK);
+
+    // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
+    // the low-level code handles this *by pointer* so we first need to allocate
+    // 8 bytes storage for {size, start} on the emscripten stack and then we
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_bytes(bytes, array.length, str);
+
+    // The compiled pn_data_put_symbol takes the pn_bytes_t by reference not value.
+    this._check(_pn_data_put_symbol(this._data, bytes));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * If the current node is a list node, return the number of elements,
+ * otherwise return zero. List elements can be accessed by entering
+ * the list.
+ * <pre>
+ *  var count = data.getLISTNODE();
+ *  data.enter();
+ *  for (var i = 0; i < count; i++) {
+ *      var type = data.next();
+ *      if (type === proton.Data.STRING) {
+ *          console.log(data.getSTRING());
+ *      }
+ *  }
+ *  data.exit();
+ * </pre>
+ * @method getLISTNODE
+ * @memberof! proton.Data#
+ * @returns {number} the number of elements if the current node is a list,
+ *          zero otherwise.
+ */
+_Data_['getLISTNODE'] = function() {
+    return _pn_data_get_list(this._data);
+};
+
+/**
+ * If the current node is a map, return the number of child elements,
+ * otherwise return zero. Key value pairs can be accessed by entering
+ * the map.
+ * <pre>
+ *  var count = data.getMAPNODE();
+ *  data.enter();
+ *  for (var i = 0; i < count/2; i++) {
+ *      var type = data.next();
+ *      if (type === proton.Data.STRING) {
+ *          console.log(data.getSTRING());
+ *      }
+ *  }
+ *  data.exit();
+ * </pre>
+ * @method getMAPNODE
+ * @memberof! proton.Data#
+ * @returns {number} the number of elements if the current node is a list,
+ *          zero otherwise.
+ */
+_Data_['getMAPNODE'] = function() {
+    return _pn_data_get_map(this._data);
+};
+
+/**
+ * If the current node is an array, return an object containing the tuple of the
+ * element count, a boolean indicating whether the array is described, and the
+ * type of each element, otherwise return {count: 0, described: false, type: null).
+ * Array data can be accessed by entering the array.
+ * <pre>
+ *  // Read an array of strings with a symbolic descriptor
+ *  var metadata = data.getARRAYNODE();
+ *  var count = metadata.count;
+ *  data.enter();
+ *  data.next();
+ *  console.log("Descriptor:" + data.getSYMBOL());
+ *  for (var i = 0; i < count; i++) {
+ *      var type = data.next();
+ *      console.log("Element:" + data.getSTRING());
+ *  }
+ *  data.exit();
+ * </pre>
+ * @method getARRAYNODE
+ * @memberof! proton.Data#
+ * @returns {object} the tuple of the element count, a boolean indicating whether
+ *          the array is described, and the type of each element.
+ */
+_Data_['getARRAYNODE'] = function() {
+    var count = _pn_data_get_array(this._data);
+    var described = (_pn_data_is_array_described(this._data) > 0);
+    var type = _pn_data_get_array_type(this._data);
+    type = (type == -1) ? null : type;
+    return {'count': count, 'described': described, 'type': type};
+};
+
+/**
+ * Checks if the current node is a described node. The descriptor and value may
+ * be accessed by entering the described node.
+ * <pre>
+ *  // read a symbolically described string
+ *  assert(data.isDESCRIBEDNODE()); // will error if the current node is not described
+ *  data.enter();
+ *  console.log(data.getSYMBOL());
+ *  console.log(data.getSTRING());
+ *  data.exit();
+ * </pre>
+ * @method isDESCRIBEDNODE
+ * @memberof! proton.Data#
+ * @returns {boolean} true iff the current node is a described, false otherwise.
+ */
+_Data_['isDESCRIBEDNODE'] = function() {
+    return _pn_data_is_described(this._data);
+};
+
+/**
+ * @method getNULL
+ * @memberof! proton.Data#
+ * @returns a null value.
+ */
+_Data_['getNULL'] = function() {
+    return null;
+};
+
+/**
+ * Checks if the current node is a null.
+ * @method isNULL
+ * @memberof! proton.Data#
+ * @returns {boolean} true iff the current node is null.
+ */
+_Data_['isNULL'] = function() {
+    return (_pn_data_is_null(this._data) > 0);
+};
+
+/**
+ * @method getBOOL
+ * @memberof! proton.Data#
+ * @returns {boolean} a boolean value if the current node is a boolean, returns
+ *          false otherwise.
+ */
+_Data_['getBOOL'] = function() {
+    return (_pn_data_get_bool(this._data) > 0);
+};
+
+/**
+ * @method getUBYTE
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is an unsigned byte, returns 0 otherwise.
+ */
+_Data_['getUBYTE'] = function() {
+    return _pn_data_get_ubyte(this._data) & 0xFF; // & 0xFF converts to unsigned;
+};
+
+/**
+ * @method getBYTE
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a signed byte, returns 0 otherwise.
+ */
+_Data_['getBYTE'] = function() {
+    return _pn_data_get_byte(this._data);
+};
+
+/**
+ * @method getUSHORT
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is an unsigned short, returns 0 otherwise.
+ */
+_Data_['getUSHORT'] = function() {
+    return _pn_data_get_ushort(this._data) & 0xFFFF; // & 0xFFFF converts to unsigned;
+};
+
+/**
+ * @method getSHORT
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a signed short, returns 0 otherwise.
+ */
+_Data_['getSHORT'] = function() {
+    return _pn_data_get_short(this._data);
+};
+
+/**
+ * @method getUINT
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is an unsigned int, returns 0 otherwise.
+ */
+_Data_['getUINT'] = function() {
+    var value = _pn_data_get_uint(this._data);
+    return (value > 0) ? value : 4294967296 + value; // 4294967296 == 2^32
+};
+
+/**
+ * @method getINT
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a signed int, returns 0 otherwise.
+ */
+_Data_['getINT'] = function() {
+    return _pn_data_get_int(this._data);
+};
+
+/**
+ * @method getCHAR
+ * @memberof! proton.Data#
+ * @returns {string} the character represented by the unicode value of the current node.
+ */
+_Data_['getCHAR'] = function() {
+    return String.fromCharCode(_pn_data_get_char(this._data));
+};
+
+/**
+ * Retrieve an unsigned long value. N.B. large values can suffer from a loss of
+ * precision as JavaScript numbers are restricted to 64 bit double values.
+ * @method getULONG
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Long} value if the current node is an unsigned long, returns 0 otherwise.
+ */
+_Data_['getULONG'] = function() {
+    var low = _pn_data_get_ulong(this._data);
+    var high = Runtime.getTempRet0();
+    var long = new Data.Long(low, high);
+    long = long.toNumber();
+    return (long >= 0) ? long : Data.Long.TWO_PWR_64_DBL_ + long;
+};
+
+/**
+ * Retrieve a signed long value. N.B. large values can suffer from a loss of
+ * precision as JavaScript numbers are restricted to 64 bit double values.
+ * @method getLONG
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Long} value if the current node is a signed long, returns 0 otherwise.
+ */
+_Data_['getLONG'] = function() {
+    // Getting the long is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to hold
+    // the 64 bit number and Data.Long.toNumber() to convert it back into a
+    // JavaScript number.
+    var low = _pn_data_get_long(this._data);
+    var high = Runtime.getTempRet0();
+    var long = new Data.Long(low, high);
+    long = long.toNumber();
+    return long;
+};
+
+/**
+ * @method getTIMESTAMP
+ * @memberof! proton.Data#
+ * @returns {Date} a native JavaScript Date instance representing the timestamp.
+ */
+_Data_['getTIMESTAMP'] = function() {
+    // Getting the timestamp is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to hold
+    // the 64 bit number and Data.Long.toNumber() to convert it back into a
+    // JavaScript number.
+    var low =  _pn_data_get_timestamp(this._data);
+    var high = Runtime.getTempRet0();
+    var long = new Data.Long(low, high);
+    long = long.toNumber();
+    return new Date(long);
+};
+
+/**
+ * Retrieves a  float value. N.B. converting between floats and doubles is imprecise
+ * so the resulting value might not quite be what you expect.
+ * @method getFLOAT
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a float, returns 0 otherwise.
+ */
+_Data_['getFLOAT'] = function() {
+    return _pn_data_get_float(this._data);
+};
+
+/**
+ * @method getDOUBLE
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a double, returns 0 otherwise.
+ */
+_Data_['getDOUBLE'] = function() {
+    return _pn_data_get_double(this._data);
+};
+
+/**
+ * @method getDECIMAL32
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a decimal32, returns 0 otherwise.
+ */
+_Data_['getDECIMAL32'] = function() {
+console.log("getDECIMAL32 not properly implemented yet");
+    return _pn_data_get_decimal32(this._data);
+};
+
+/**
+ * @method getDECIMAL64
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a decimal64, returns 0 otherwise.
+ */
+_Data_['getDECIMAL64'] = function() {
+console.log("getDECIMAL64 not properly implemented yet");
+    return _pn_data_get_decimal64(this._data);
+};
+
+/**
+ * @method getDECIMAL128
+ * @memberof! proton.Data#
+ * @returns {number} value if the current node is a decimal128, returns 0 otherwise.
+ */
+_Data_['getDECIMAL128'] = function() {
+console.log("getDECIMAL128 not properly implemented yet");
+    return _pn_data_get_decimal128(this._data);
+};
+
+/**
+ * @method getUUID
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Uuid} value if the current node is a UUID, returns null otherwise.
+ */
+_Data_['getUUID'] = function() {
+    var sp = Runtime.stackSave();
+
+    // Here's the quirky bit, pn_data_get_uuid actually returns pn_uuid_t
+    // *by value* but the low-level code handles this *by pointer* so we first
+    // need to allocate 16 bytes storage for pn_uuid_t on the emscripten stack
+    // and then we pass the pointer to that storage as the first parameter to the
+    // compiled pn_data_get_uuid.
+    var bytes = allocate(16, 'i8', ALLOC_STACK); // pn_uuid_t is 16 bytes.
+    _pn_data_get_uuid(bytes, this._data);
+
+    // Create a new UUID from the bytes
+    var uuid = new Data['Uuid'](bytes);
+
+    // Tidy up the memory that we allocated on emscripten's stack.
+    Runtime.stackRestore(sp);
+
+    return uuid;
+};
+
+/**
+ * @method getBINARY
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Binary} value if the current node is a Binary, returns null otherwise.
+ */
+_Data_['getBINARY'] = function() {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_bytes bytes = pn_data_get_binary(data);
+
+    // Here's the quirky bit, pn_data_get_binary actually returns pn_bytes_t 
+    // *by value* but the low-level code handles this *by pointer* so we first
+    // need to allocate 8 bytes storage for {size, start} on the emscripten stack
+    // and then we pass the pointer to that storage as the first parameter to the
+    // compiled pn_data_get_binary.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_data_get_binary(bytes, this._data);
+
+    // The bytes variable is really of type pn_bytes_t* so we use emscripten's
+    // getValue() call to retrieve the size and then the start pointer.
+    var size  = getValue(bytes, 'i32');
+    var start = getValue(bytes + 4, '*');
+
+    // Create a proton.Data.Binary from the pn_bytes_t information.
+    var binary = new Data['Binary'](size, start);
+
+    // Tidy up the memory that we allocated on emscripten's stack.
+    Runtime.stackRestore(sp);
+
+    // If _decodeBinaryAsString is set return the stringified form of the Binary.
+    if (this._decodeBinaryAsString) {
+        return binary.toString();
+    } else {
+        return binary;
+    }
+};
+
+/**
+ * Gets a unicode String value from the current node.
+ * @method getSTRING
+ * @memberof! proton.Data#
+ * @returns {string} value if the current node is a String, returns "" otherwise.
+ */
+_Data_['getSTRING'] = function() {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_bytes bytes = pn_data_get_string(data);
+
+    // Here's the quirky bit, pn_data_get_string actually returns pn_bytes_t 
+    // *by value* but the low-level code handles this *by pointer* so we first
+    // need to allocate 8 bytes storage for {size, start} on the emscripten stack
+    // and then we pass the pointer to that storage as the first parameter to the
+    // compiled pn_data_get_string.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_data_get_string(bytes, this._data);
+
+    // The bytes variable is really of type pn_bytes_t* so we use emscripten's
+    // getValue() call to retrieve the size and then the start pointer.
+    var size  = getValue(bytes, 'i32');
+    var start = getValue(bytes + 4, '*');
+
+    // Create a native JavaScript String from the pn_bytes_t information.
+    var string = Pointer_stringify(start, size);
+
+    // Tidy up the memory that we allocated on emscripten's stack.
+    Runtime.stackRestore(sp);
+
+    return string;
+};
+
+/**
+ * Gets a symbolic value. According to the AMQP 1.0 Specification Symbols are
+ * values from a constrained domain. Although the set of possible domains is
+ * open-ended, typically the both number and size of symbols in use for any
+ * given application will be small, e.g. small enough that it is reasonable to
+ * cache all the distinct values. Symbols are encoded as ASCII characters.
+ * @method getSYMBOL
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Symbol} value if the current node is a Symbol, returns "" otherwise.
+ */
+_Data_['getSYMBOL'] = function() {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_bytes bytes = pn_data_get_symbol(data);
+
+    // Here's the quirky bit, pn_data_get_symbol actually returns pn_bytes_t 
+    // *by value* but the low-level code handles this *by pointer* so we first
+    // need to allocate 8 bytes storage for {size, start} on the emscripten stack
+    // and then we pass the pointer to that storage as the first parameter to the
+    // compiled pn_data_get_symbol.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_data_get_symbol(bytes, this._data);
+
+    // The bytes variable is really of type pn_bytes_t* so we use emscripten's
+    // getValue() call to retrieve the size and then the start pointer.
+    var size  = getValue(bytes, 'i32');
+    var start = getValue(bytes + 4, '*');
+
+    // Create a native JavaScript String from the pn_bytes_t information.
+    var string = Pointer_stringify(start, size);
+
+    // Tidy up the memory that we allocated on emscripten's stack.
+    Runtime.stackRestore(sp);
+
+    return new Data['Symbol'](string);
+};
+
+/**
+ * Performs a deep copy of the current {@link proton.Data} instance and returns it
+ * @method copy
+ * @memberof! proton.Data#
+ * @returns {proton.Data} a copy of the current {@link proton.Data} instance.
+ */
+_Data_['copy'] = function() {
+    var copy = new Data();
+    this._check(_pn_data_copy(copy._data, this._data));
+    return copy;
+};
+
+/**
+ * Format the encoded AMQP Data into a string representation and return it.
+ * @method format
+ * @memberof! proton.Data#
+ * @returns {string} a formatted string representation of the encoded Data.
+ */
+_Data_['format'] = function() {
+    var size = 1024; // Pass by reference variable - need to use setValue to initialise it.
+    while (true) {
+        setValue(size, size, 'i32'); // Set pass by reference variable.
+        var bytes = _malloc(size);   // Allocate storage from emscripten heap.
+        var err = _pn_data_format(this._data, bytes, size);
+        var size = getValue(size, 'i32'); // Dereference the real size value;
+
+        if (err === Module['Error']['OVERFLOW']) {
+            _free(bytes);
+            size *= 2;
+        } else {
+            var string = Pointer_stringify(bytes);
+            _free(bytes);
+            this._check(err)
+            return string;
+        }
+    }
+};
+
+/**
+ * Print the internal state of the {@link proton.Data} in human readable form.
+ * TODO. This seems to "crash" if compound nodes such as DESCRIBED, MAP or LIST
+ * are present in the tree, this is most likely a problem with the underlying C
+ * implementation as all the other navigation and format methods work - need to
+ * check by testing with some native C code.
+ * @method dump
+ * @memberof! proton.Data#
+ */
+_Data_['dump'] = function() {
+    _pn_data_dump(this._data);
+};
+
+/**
+ * Serialise a Native JavaScript Object into an AMQP Map.
+ * @method putMAP
+ * @memberof! proton.Data#
+ * @param {object} object the Native JavaScript Object that we wish to serialise.
+ */
+_Data_['putMAP'] = function(object) {
+    this['putMAPNODE']();
+    this['enter']();
+    for (var key in object) {
+        if (object.hasOwnProperty(key)) {
+            this['putObject'](key);
+            this['putObject'](object[key]);
+        }
+    }
+    this['exit']();
+};
+
+/**
+ * Deserialise from an AMQP Map into a Native JavaScript Object.
+ * @method getMAP
+ * @memberof! proton.Data#
+ * @returns {object} the deserialised Native JavaScript Object.
+ */
+_Data_['getMAP'] = function() {
+    if (this['enter']()) {
+        var result = {};
+        while (this['next']()) {
+            var key = this['getObject']();
+            var value = null;
+            if (this['next']()) {
+                value = this['getObject']();
+            }
+            result[key] = value;
+        }
+        this['exit']();
+        return result;
+    }
+};
+
+/**
+ * Serialise a Native JavaScript Array into an AMQP List.
+ * @method putLIST
+ * @memberof! proton.Data#
+ * @param {Array} array the Native JavaScript Array that we wish to serialise.
+ */
+_Data_['putLIST'] = function(array) {
+    this['putLISTNODE']();
+    this['enter']();
+    for (var i = 0, len = array.length; i < len; i++) {
+        this['putObject'](array[i]);
+    }
+    this['exit']();
+};
+
+/**
+ * Deserialise from an AMQP List into a Native JavaScript Array.
+ * @method getLIST
+ * @memberof! proton.Data#
+ * @returns {Array} the deserialised Native JavaScript Array.
+ */
+_Data_['getLIST'] = function() {
+    if (this['enter']()) {
+        var result = [];
+        while (this['next']()) {
+            result.push(this['getObject']());
+        }
+        this['exit']();
+        return result;
+    }
+};
+
+/**
+ * Serialise a proton.Data.Described into an AMQP Described.
+ * @method putDESCRIBED
+ * @memberof! proton.Data#
+ * @param {proton.Data.Described} d the proton.Data.Described that we wish to serialise.
+ */
+_Data_['putDESCRIBED'] = function(d) {
+    this['putDESCRIBEDNODE']();
+    this['enter']();
+    this['putObject'](d['descriptor']);
+    this['putObject'](d['value']);
+    this['exit']();
+};
+
+/**
+ * Deserialise from an AMQP Described into a proton.Data.Described.
+ * @method getDESCRIBED
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Described} the deserialised proton.Data.Described.
+ */
+_Data_['getDESCRIBED'] = function() {
+    if (this['enter']()) {
+        this['next']();
+        var descriptor = this['getObject']();
+        this['next']();
+        var value = this['getObject']();
+        this['exit']();
+        return new Data['Described'](value, descriptor);
+    }
+};
+
+/**
+ * Serialise a proton.Data.Array or JavaScript TypedArray into an AMQP Array.
+ * @method putARRAY
+ * @memberof! proton.Data#
+ * @param {object} a the proton.Data.Array or TypedArray that we wish to serialise.
+ */
+_Data_['putARRAY'] = function(a) {
+    var type = 1;
+    var descriptor = 'TypedArray';
+    var array = a;
+
+    if (a instanceof Data['Array']) { // Array is a proton.Data.Array
+        type = Data[a['type']]; // Find the integer type from its name string.
+        descriptor = a['descriptor'];
+        array = a['elements'];
+    } else { // Array is a Native JavaScript TypedArray so work out the right type.
+        if (a instanceof Int8Array) {
+            type = Data['BYTE'];
+        } else if (a instanceof Uint8Array || a instanceof Uint8ClampedArray) {
+            type = Data['UBYTE'];
+        } else if (a instanceof Int16Array) {
+            type = Data['SHORT'];
+        } else if (a instanceof Uint16Array) {
+            type = Data['USHORT'];
+        } else if (a instanceof Int32Array) {
+            type = Data['INT'];
+        } else if (a instanceof Uint32Array) {
+            type = Data['UINT'];
+        } else if (a instanceof Float32Array) {
+            type = Data['FLOAT'];
+        } else if (a instanceof Float64Array) {
+            type = Data['DOUBLE'];
+        }
+    }
+
+    var described = descriptor != null;
+
+    this['putARRAYNODE'](described, type);
+    this['enter']();
+    if (described) {
+        this['putObject'](descriptor);
+    }
+    var putter = 'put' + Data['TypeNames'][type];
+    for (var i = 0, len = array.length; i < len; i++) {
+        var value = array[i];
+        value = (value instanceof Data.TypedNumber) ? value.value : value;
+        this[putter](value);
+    }
+    this['exit']();
+};
+
+/**
+ * Deserialise from an AMQP Array into a proton.Data.Array.
+ * @method getARRAY
+ * @memberof! proton.Data#
+ * @returns {proton.Data.Array} the deserialised proton.Data.Array.
+ */
+_Data_['getARRAY'] = function() {
+    var metadata = this['getARRAYNODE']();
+    var count = metadata['count'];
+    var described = metadata['described'];
+    var type = metadata['type'];
+
+    if (type === null) {
+        return null;
+    }
+
+    var elements = null;
+    if (typeof ArrayBuffer === 'function') {
+        if (type === Data['BYTE']) {
+            elements = new Int8Array(count);
+        } else if (type === Data['UBYTE']) {
+            elements = new Uint8Array(count);
+        } else if (type === Data['SHORT']) {
+            elements = new Int16Array(count);
+        } else if (type === Data['USHORT']) {
+            elements = new Uint16Array(count);
+        } else if (type === Data['INT']) {
+            elements = new Int32Array(count);
+        } else if (type === Data['UINT']) {
+            elements = new Uint32Array(count);
+        } else if (type === Data['FLOAT']) {
+            elements = new Float32Array(count);
+        } else if (type === Data['DOUBLE']) {
+            elements = new Float64Array(count);
+        } else {
+            elements = new Array(count);
+        }
+    } else {
+        elements = new Array(count);
+    }
+
+    if (this['enter']()) {
+        var descriptor; // Deliberately initialised as undefined not null.
+        if (described) {
+            this['next']();
+            descriptor = this['getObject']();
+        }
+
+        for (var i = 0; i < count; i++) {
+            this['next']();
+            elements[i] = this['getObject']();
+        }
+
+        this['exit']();
+        if (descriptor === 'TypedArray') {
+            return elements;
+        } else {
+            return new Data['Array'](type, elements, descriptor);
+        }
+    }
+};
+
+/**
+ * This method is the entry point for serialising native JavaScript types into
+ * AMQP types. In an ideal world there would be a nice clean one to one mapping
+ * and we could employ a look-up table but in practice the JavaScript type system
+ * doesn't really lend itself to that and we have to employ extra checks,
+ * heuristics and inferences.
+ * @method putObject
+ * @memberof! proton.Data#
+ * @param {object} obj the JavaScript Object or primitive to be serialised.
+ */
+_Data_['putObject'] = function(obj) {
+//console.log("Data.putObject " + obj);
+
+    if (obj == null) { // == Checks for null and undefined.
+        this['putNULL']();
+    } else if (Data.isString(obj)) {
+        var quoted = obj.match(/(['"])[^'"]*\1/);
+        if (quoted) { // If a quoted string extract the string inside the quotes.
+            obj = quoted[0].slice(1, -1);
+        }
+        this['putSTRING'](obj);
+    } else if (obj instanceof Date) {
+        this['putTIMESTAMP'](obj);
+    } else if (obj instanceof Data['Uuid']) {
+        this['putUUID'](obj);
+    } else if (obj instanceof Data['Binary']) {
+        this['putBINARY'](obj);
+    } else if (obj instanceof Data['Symbol']) {
+        this['putSYMBOL'](obj);
+    } else if (obj instanceof Data['Described']) {
+        this['putDESCRIBED'](obj);
+    } else if (obj instanceof Data['Array']) {
+        this['putARRAY'](obj);
+    } else if (obj.buffer && (typeof ArrayBuffer === 'function') && 
+               obj.buffer instanceof ArrayBuffer) {
+        this['putARRAY'](obj);
+    } else if (obj instanceof Data.TypedNumber) { // Dot notation used for "protected" inner class.
+        // Call the appropriate serialisation method based upon the numerical type.
+        this['put' + obj.type](obj.value);
+    } else if (Data.isNumber(obj)) {
+        /**
+         * This block encodes standard JavaScript numbers by making some inferences.
+         * Encoding JavaScript numbers is surprisingly complex and has several
+         * gotchas. The code here tries to do what the author believes is the
+         * most "intuitive" encoding of the native JavaScript Number. It first
+         * tries to identify if the number is an integer or floating point type
+         * by checking if the number modulo 1 is zero (i.e. if it has a remainder
+         * then it's a floating point type, which is encoded here as a double).
+         * If the number is an integer type a test is made to check if it is a
+         * 32 bit Int value. N.B. gotcha - JavaScript automagically coerces floating
+         * point numbers with a zero Fractional Part into an *exact* integer so
+         * numbers like 1.0, 100.0 etc. will be encoded as int or long here,
+         * which is unlikely to be what is wanted. There's no easy "transparent"
+         * way around this. The TypedNumber approach above allows applications
+         * to express more explicitly what is required, for example (1.0).float()
+         * (1).ubyte(), (5).long() etc.
+         */
+        if (obj % 1 === 0) {
+            if (obj === (obj|0)) { // the |0 coerces to a 32 bit value.
+                // 32 bit integer - encode as an INT.
+                this['putINT'](obj);
+            } else { // Longer than 32 bit - encode as a Long.
+                this['putLONG'](obj);
+            }
+        } else { // Floating point type - encode as a Double
+            this['putDOUBLE'](obj);
+        }
+    } else if (Data.isBoolean(obj)) {
+        this['putBOOL'](obj);
+    } else if (Data.isArray(obj)) { // Native JavaScript Array
+        this['putLIST'](obj);
+    } else {
+        this['putMAP'](obj);
+    }
+};
+
+/**
+ * @method getObject
+ * @memberof! proton.Data#
+ * @returns {object} the JavaScript Object or primitive being deserialised.
+ */
+_Data_['getObject'] = function() {
+    var type = Data['TypeNames'][this.type()];
+    type = type ? type : 'NULL';
+    var getter = 'get' + type;
+    return this[getter]();
+};
+
diff --git a/proton-c/bindings/javascript/error.js b/proton-c/bindings/javascript/error.js
new file mode 100644
index 0000000..4069bef
--- /dev/null
+++ b/proton-c/bindings/javascript/error.js
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                   Status                                  */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Export Status Enum, avoiding minification.
+ * @enum
+ * @alias Status
+ * @memberof proton
+ */
+Module['Status'] = {
+    /** PN_STATUS_UNKNOWN */  'UNKNOWN':  0, // The tracker is unknown.
+    /** PN_STATUS_PENDING */  'PENDING':  1, // The message is in flight.
+                                             // For outgoing messages, use messenger.isBuffered()
+                                             // to see if it has been sent or not.
+    /** PN_STATUS_ACCEPTED */ 'ACCEPTED': 2, // The message was accepted.
+    /** PN_STATUS_REJECTED */ 'REJECTED': 3, // The message was rejected.
+    /** PN_STATUS_RELEASED */ 'RELEASED': 4, // The message was released.
+    /** PN_STATUS_MODIFIED */ 'MODIFIED': 5, // The message was modified.
+    /** PN_STATUS_ABORTED */  'ABORTED':  6, // The message was aborted.
+    /** PN_STATUS_SETTLED */  'SETTLED':  7  // The remote party has settled the message.
+};
+
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                   Error                                   */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Export Error Enum, avoiding minification.
+ * @enum
+ * @alias Error
+ * @memberof proton
+ */
+Module['Error'] = {
+    /** PN_EOS */        'EOS':        -1,
+    /** PN_ERR */        'ERR':        -2,
+    /** PN_OVERFLOW */   'OVERFLOW':   -3,
+    /** PN_UNDERFLOW */  'UNDERFLOW':  -4,
+    /** PN_STATE_ERR */  'STATE_ERR':  -5,
+    /** PN_ARG_ERR */    'ARG_ERR':    -6,
+    /** PN_TIMEOUT */    'TIMEOUT':    -7,
+    /** PN_INTR */       'INTR':       -8,
+    /** PN_INPROGRESS */ 'INPROGRESS': -9
+};
+
+
+/*****************************************************************************/
+/*                                                                           */
+/*                               MessengerError                              */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.MessengerError instance.
+ * @classdesc This class is a subclass of Error.
+ * @constructor proton.MessengerError
+ * @param {string} message the error message.
+ */
+Module['MessengerError'] = function(message) { // MessengerError constructor.
+    this.name = "MessengerError";
+    this.message = (message || "");
+};
+
+Module['MessengerError'].prototype = new Error();
+Module['MessengerError'].prototype.constructor = Module['MessengerError'];
+
+Module['MessengerError'].prototype.toString = function() {
+    return this.name + ': ' + this.message;
+};
+
+
+/*****************************************************************************/
+/*                                                                           */
+/*                              SubscriptionError                            */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.SubscriptionError instance.
+ * @classdesc This class is a subclass of MessengerError.
+ * @constructor proton.SubscriptionError
+ * @param {string} source the address that we want to subscribe to.
+ * @param {string} message the error message.
+ */
+Module['SubscriptionError'] = function(source, message) { // SubscriptionError constructor.
+    this.name = "SubscriptionError";
+    this.source = source;
+    this.message = (message || "");
+};
+
+Module['SubscriptionError'].prototype = new Module['MessengerError']();
+Module['SubscriptionError'].prototype.constructor = Module['SubscriptionError'];
+
+Module['SubscriptionError'].prototype.toString = function() {
+    return this.name + ': ' + this.source + ': ' + this.message;
+};
+
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                MessageError                               */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.MessageError instance.
+ * @classdesc This class is a subclass of Error.
+ * @constructor proton.MessageError
+ * @param {string} message the error message.
+ */
+Module['MessageError'] = function(message) { // MessageError constructor.
+    this.name = "MessageError";
+    this.message = (message || "");
+};
+
+Module['MessageError'].prototype = new Error();
+Module['MessageError'].prototype.constructor = Module['MessageError'];
+
+Module['MessageError'].prototype.toString = function() {
+    return this.name + ': ' + this.message;
+};
+
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                  DataError                                */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.DataError instance.
+ * @classdesc This class is a subclass of Error.
+ * @constructor proton.DataError
+ * @param {string} message the error message.
+ */
+Module['DataError'] = function(message) { // DataError constructor.
+    this.name = "DataError";
+    this.message = (message || "");
+};
+
+Module['DataError'].prototype = new Error();
+Module['DataError'].prototype.constructor = Module['DataError'];
+
+Module['DataError'].prototype.toString = function() {
+    return this.name + ': ' + this.message;
+};
+
diff --git a/proton-c/bindings/javascript/message.js b/proton-c/bindings/javascript/message.js
new file mode 100644
index 0000000..564cc6e
--- /dev/null
+++ b/proton-c/bindings/javascript/message.js
@@ -0,0 +1,848 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                  Message                                  */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.Message instance.
+ * @classdesc This class is a mutable holder of message content that may be used
+ * to generate and encode or decode and access AMQP formatted message data.
+ * @constructor proton.Message
+ * @property {object} instructions delivery instructions for the message.
+ * @property {object} annotations infrastructure defined message annotations.
+ * @property {object} properties application defined message properties.
+ * @property {object} body message body as a native JavaScript Object.
+ * @property {object} data message body as a proton.Data Object.
+ */
+Module['Message'] = function() { // Message Constructor.
+    this._message = _pn_message();
+    this._id = new Data(_pn_message_id(this._message));
+    this._correlationId = new Data(_pn_message_correlation_id(this._message));
+
+    // ************************* Public properties ****************************
+
+    this['instructions'] = null;
+    this['annotations'] = null;
+
+    // Intitialise with an empty Object so we can set properties in a natural way.
+    // message.properties.prop1 = "foo";
+    // message.properties.prop2 = "bar";
+    this['properties'] = {};
+
+    this['body'] = null;
+    this['data'] = null;
+};
+
+// Expose constructor as package scope variable to make internal calls less verbose.
+var Message = Module['Message'];
+
+// Expose prototype as a variable to make method declarations less verbose.
+var _Message_ = Message.prototype;
+
+// ************************** Class properties ********************************
+
+Message['DEFAULT_PRIORITY'] = 4; /** Default priority for messages.*/
+
+// ************************* Protected methods ********************************
+
+// We use the dot notation rather than associative array form for protected
+// methods so they are visible to this "package", but the Closure compiler will
+// minify and obfuscate names, effectively making a defacto "protected" method.
+
+/**
+ * This helper method checks the supplied error code, converts it into an
+ * exception and throws the exception. This method will try to use the message
+ * populated in pn_message_error(), if present, but if not it will fall
+ * back to using the basic error code rendering from pn_code().
+ * @param code the error code to check.
+ */
+_Message_._check = function(code) {
+    if (code < 0) {
+        var errno = this['getErrno']();
+        var message = errno ? this['getError']() : Pointer_stringify(_pn_code(code));
+
+        throw new Module['MessageError'](message);
+    } else {
+        return code;
+    }
+};
+
+/**
+ * Encode the Message prior to sending on the wire.
+ */
+_Message_._preEncode = function() {
+    // A Message Object may be reused so we create new Data instances and clear
+    // the state for them each time put() gets called.
+    var inst = new Data(_pn_message_instructions(this._message));
+    var ann = new Data(_pn_message_annotations(this._message));
+    var props = new Data(_pn_message_properties(this._message));
+    var body = new Data(_pn_message_body(this._message));
+
+    inst.clear();
+    if (this['instructions']) {
+        inst['putObject'](this['instructions']);
+    }
+
+    ann.clear();
+    if (this['annotations']) {
+        ann['putObject'](this['annotations']);
+    }
+
+    props.clear();
+    if (this['properties']) {
+        props['putObject'](this['properties']);
+    }
+
+    body.clear();
+    if (this['body']) {
+        var contentType = this['getContentType']();
+        if (contentType) {
+            var value = this['body'];
+            if (contentType === 'application/json' && JSON) { // Optionally encode body as JSON.
+                var json = JSON.stringify(value);
+                value = new Data['Binary'](json);
+            } else if (!(value instanceof Data['Binary'])) { // Construct a Binary from the body
+                value = new Data['Binary'](value);
+            }
+            // As content-type is set we send as an opaque AMQP data section.
+            this['setInferred'](true);
+            body['putBINARY'](value);
+        } else { // By default encode body using the native AMQP type system.
+            this['setInferred'](false);
+            body['putObject'](this['body']);
+        }
+    }
+};
+
+/**
+ * Decode the Message after receiving off the wire.
+ * @param {boolean} decodeBinaryAsString if set decode any AMQP Binary payload
+ *        objects as strings. This can be useful as the data in Binary objects
+ *        will be overwritten with subsequent calls to get, so they must be
+ *        explicitly copied. Needless to say it is only safe to set this flag if
+ *        you know that the data you are dealing with is actually a string, for
+ *        example C/C++ applications often seem to encode strings as AMQP binary,
+ *        a common cause of interoperability problems.
+ */
+_Message_._postDecode = function(decodeBinaryAsString) {
+    var inst = new Data(_pn_message_instructions(this._message));
+    var ann = new Data(_pn_message_annotations(this._message));
+    var props = new Data(_pn_message_properties(this._message));
+    var body = new Data(_pn_message_body(this._message), decodeBinaryAsString);
+
+    if (inst.next()) {
+        this['instructions'] = inst['getObject']();
+    } else {
+        this['instructions'] = {};
+    }
+
+    if (ann.next()) {
+        this['annotations'] = ann['getObject']();
+    } else {
+        this['annotations'] = {};
+    }
+
+    if (props.next()) {
+        this['properties'] = props['getObject']();
+    } else {
+        this['properties'] = {};
+    }
+
+    if (body.next()) {
+        this['data'] = body;
+        this['body'] = body['getObject']();
+        var contentType = this['getContentType']();
+        if (contentType) {
+            if (contentType === 'application/json' && JSON) {
+                var json = this['body'].toString(); // Convert Binary to String.
+                this['body'] = JSON.parse(json);
+            } else if (contentType.indexOf('text/') === 0) { // It's a text/* MIME type
+                this['body'] = this['body'].toString(); // Convert Binary to String.
+            }
+        }
+    } else {
+        this['data'] = null;
+        this['body'] = null;
+    }
+};
+
+// *************************** Public methods *********************************
+
+/**
+ * Free the Message.
+ * <p>
+ * N.B. This method has to be called explicitly in JavaScript as we can't
+ * intercept finalisers, so we need to remember to free before removing refs.
+ * @method free
+ * @memberof! proton.Message#
+ */
+_Message_['free'] = function() {
+    _pn_message_free(this._message);
+};
+
+/**
+ * @method getErrno
+ * @memberof! proton.Message#
+ * @returns {number the most recent error message code.
+ */
+_Message_['getErrno'] = function() {
+    return _pn_message_errno(this._message);
+};
+
+/**
+ * @method getError
+ * @memberof! proton.Message#
+ * @returns {string} the most recent error message as a String.
+ */
+_Message_['getError'] = function() {
+    return Pointer_stringify(_pn_error_text(_pn_message_error(this._message)));
+};
+
+/**
+ * Clears the contents of the Message. All fields will be reset to their default values.
+ * @method clear
+ * @memberof! proton.Message#
+ */
+_Message_['clear'] = function() {
+    _pn_message_clear(this._message);
+    this['instructions'] = null;
+    this['annotations'] = null;
+    this['properties'] = {};
+    this['body'] = null;
+    this['data'] = null;
+};
+
+/**
+ * Get the inferred flag for a message.
+ * <p>
+ * The inferred flag for a message indicates how the message content
+ * is encoded into AMQP sections. If inferred is true then binary and
+ * list values in the body of the message will be encoded as AMQP DATA
+ * and AMQP SEQUENCE sections, respectively. If inferred is false,
+ * then all values in the body of the message will be encoded as AMQP
+ * VALUE sections regardless of their type. Use
+ * {@link proton.Message.setInferred} to set the value.
+ * @method isInferred
+ * @memberof! proton.Message#
+ * @returns {boolean} true iff the inferred flag for the message is set.
+ */
+_Message_['isInferred'] = function() {
+    return (_pn_message_is_inferred(this._message) > 0);
+};
+
+/**
+ * Set the inferred flag for a message. See {@link proton.Message.isInferred} 
+ * for a description of what the inferred flag is.
+ * @method setInferred
+ * @memberof! proton.Message#
+ * @param {boolean} inferred the new value of the inferred flag.
+ */
+_Message_['setInferred'] = function(inferred) {
+    this._check(_pn_message_set_inferred(this._message, inferred));
+};
+
+/**
+ * Get the durable flag for a message.
+ * <p>
+ * The durable flag indicates that any parties taking responsibility
+ * for the message must durably store the content. Use
+ * {@link proton.Message.setDurable} to set the value.
+ * @method isDurable
+ * @memberof! proton.Message#
+ * @returns {boolean} true iff the durable flag for the message is set.
+ */
+_Message_['isDurable'] = function() {
+    return (_pn_message_is_durable(this._message) > 0);
+};
+
+/**
+ * Set the durable flag for a message. See {@link proton.Message.isDurable} 
+ * for a description of what the durable flag is.
+ * @method setDurable
+ * @memberof! proton.Message#
+ * @param {boolean} durable the new value of the durable flag.
+ */
+_Message_['setDurable'] = function(durable) {
+    this._check(_pn_message_set_durable(this._message, durable));
+};
+
+/**
+ * Get the priority for a message.
+ * <p>
+ * The priority of a message impacts ordering guarantees. Within a
+ * given ordered context, higher priority messages may jump ahead of
+ * lower priority messages. Priority range is 0..255
+ * @method getPriority
+ * @memberof! proton.Message#
+ * @returns {number} the priority of the Message.
+ */
+_Message_['getPriority'] = function() {
+    return _pn_message_get_priority(this._message) & 0xFF; // & 0xFF converts to unsigned.
+};
+
+/**
+ * Set the priority of the Message. See {@link proton.Message.getPriority}
+ * for details on message priority.
+ * @method setPriority
+ * @memberof! proton.Message#
+ * @param {number} priority the address we want to send the Message to.
+ */
+_Message_['setPriority'] = function(priority) {
+    this._check(_pn_message_set_priority(this._message, priority));
+};
+
+/**
+ * Get the ttl for a message.
+ * <p>
+ * The ttl for a message determines how long a message is considered
+ * live. When a message is held for retransmit, the ttl is
+ * decremented. Once the ttl reaches zero, the message is considered
+ * dead. Once a message is considered dead it may be dropped. Use
+ * {@link proton.Message.setTTL} to set the ttl for a message.
+ * @method getTTL
+ * @memberof! proton.Message#
+ * @returns {number} the ttl in milliseconds.
+ */
+_Message_['getTTL'] = function() {
+    return _pn_message_get_ttl(this._message);
+};
+
+/**
+ * Set the ttl for a message. See {@link proton.Message.getTTL}
+ * for a detailed description of message ttl.
+ * @method setTTL
+ * @memberof! proton.Message#
+ * @param {number} ttl the new value for the message ttl in milliseconds.
+ */
+_Message_['setTTL'] = function(ttl) {
+    this._check(_pn_message_set_ttl(this._message, ttl));
+};
+
+/**
+ * Get the first acquirer flag for a message.
+ * <p>
+ * When set to true, the first acquirer flag for a message indicates
+ * that the recipient of the message is the first recipient to acquire
+ * the message, i.e. there have been no failed delivery attempts to
+ * other acquirers. Note that this does not mean the message has not
+ * been delivered to, but not acquired, by other recipients.
+ * @method isFirstAcquirer
+ * @memberof! proton.Message#
+ * @returns {boolean} true iff the first acquirer flag for the message is set.
+ */
+_Message_['isFirstAcquirer'] = function() {
+    return (_pn_message_is_first_acquirer(this._message) > 0);
+};
+
+/**
+ * Set the first acquirer flag for a message. See {@link proton.Message.isFirstAcquirer} 
+ * for details on the first acquirer flag.
+ * @method setFirstAcquirer
+ * @memberof! proton.Message#
+ * @param {boolean} first the new value of the first acquirer flag.
+ */
+_Message_['setFirstAcquirer'] = function(first) {
+    this._check(_pn_message_set_first_acquirer(this._message, first));
+};
+
+/**
+ * Get the delivery count for a message.
+ * <p>
+ * The delivery count field tracks how many attempts have been made to
+ * deliver a message. Use {@link proton.Message.setDeliveryCount} to set
+ * the delivery count for a message.
+ * @method getDeliveryCount
+ * @memberof! proton.Message#
+ * @returns {number} the delivery count for the message.
+ */
+_Message_['getDeliveryCount'] = function() {
+    return _pn_message_get_delivery_count(this._message);
+};
+
+/**
+ * Set the delivery count for a message. See {@link proton.Message.getDeliveryCount}
+ * for details on what the delivery count means.
+ * @method setDeliveryCount
+ * @memberof! proton.Message#
+ * @param {number} count the new delivery count.
+ */
+_Message_['setDeliveryCount'] = function(count) {
+    this._check(_pn_message_set_delivery_count(this._message, count));
+};
+
+/**
+ * Get the id for a message.
+ * <p>
+ * The message id provides a globally unique identifier for a message.
+ * A message id can be an a string, an unsigned long, a uuid or a binary value.
+ * @method getID
+ * @memberof! proton.Message#
+ * @returns {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} the message id.
+ */
+_Message_['getID'] = function() {
+    return this._id['getObject']();
+};
+
+/**
+ * Set the id for a message. See {@link proton.Message.getID}
+ * for more details on the meaning of the message id. Note that only string,
+ * unsigned long, uuid, or binary values are permitted.
+ * @method setID
+ * @memberof! proton.Message#
+ * @param {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} id the
+ *        new value of the message id.
+ */
+_Message_['setID'] = function(id) {
+    this._id['rewind']();
+    if (Data.isNumber(id)) {
+        this._id['putULONG'](id);
+    } else {
+        this._id['putObject'](id);
+    }
+};
+
+/**
+ * Get the user id of the message creator.
+ * <p>
+ * The underlying raw data of the returned {@link proton.Data.Binary} will be
+ * valid until any one of the following operations occur:
+ * <pre>
+ *  - {@link proton.Message.free}
+ *  - {@link proton.Message.clear}
+ *  - {@link proton.Message.setUserID}
+ * </pre>
+ * @method getUserID
+ * @memberof! proton.Message#
+ * @returns {proton.Data.Binary} the message's user id.
+ */
+_Message_['getUserID'] = function() {
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_bytes_t bytes = pn_message_get_user_id(message);
+
+    // Here's the quirky bit, pn_message_get_user_id actually returns pn_bytes_t 
+    // *by value* but the low-level code handles this *by pointer* so we first
+    // need to allocate 8 bytes storage for {size, start} on the emscripten stack
+    // and then we pass the pointer to that storage as the first parameter to the
+    // compiled pn_message_get_user_id.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_message_get_user_id(bytes, this._message);
+
+    // The bytes variable is really of type pn_bytes_t* so we use emscripten's
+    // getValue() call to retrieve the size and then the start pointer.
+    var size  = getValue(bytes, 'i32');
+    var start = getValue(bytes + 4, '*');
+
+    // Create a proton.Data.Binary from the pn_bytes_t information.
+    var binary = new Data['Binary'](size, start);
+
+    // Tidy up the memory that we allocated on emscripten's stack.
+    Runtime.stackRestore(sp);
+
+    return binary;
+};
+
+/**
+ * Set the user id for a message. This method takes a {@link proton.Data.Binary}
+ * consuming the underlying raw data in the process. For convenience this method
+ * also accepts a {@link proton.Data.Uuid}, number or string, converting them to a
+ * Binary internally. N.B. getUserID always returns a {@link proton.Data.Binary}
+ * even if a string or {@link proton.Data.Uuid} has been passed to setUserID.
+ * @method setUserID
+ * @memberof! proton.Message#
+ * @param {(string|proton.Data.Uuid)} id the new user id for the message.
+ */
+_Message_['setUserID'] = function(id) {
+    // If the id parameter is a proton.Data.Binary use it otherwise create a Binary
+    // using the string form of the parameter that was passed.
+    id = (id instanceof Data['Binary']) ? id : new Data['Binary']('' + id);
+
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_message_set_user_id(message, pn_bytes(id.size, id.start));
+
+    // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
+    // the low-level code handles this *by pointer* so we first need to allocate
+    // 8 bytes storage for {size, start} on the emscripten stack and then we
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_bytes(bytes, id.size, id.start);
+
+    // The compiled pn_message_set_user_id takes the pn_bytes_t by reference not value.
+    this._check(_pn_message_set_user_id(this._message, bytes));
+
+    // After calling _pn_message_set_user_id the underlying Message object "owns" the
+    // binary data, so we can call free on the proton.Data.Binary instance to
+    // release any storage it has acquired back to the emscripten heap.
+    id['free']();
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the address for a message.
+ * @method getAddress
+ * @memberof! proton.Message#
+ * @returns {string} the address of the Message.
+ */
+_Message_['getAddress'] = function() {
+    return Pointer_stringify(_pn_message_get_address(this._message));
+};
+
+/**
+ * Set the address of the Message.
+ * @method setAddress
+ * @memberof! proton.Message#
+ * @param {string} address the address we want to send the Message to.
+ */
+_Message_['setAddress'] = function(address) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_address(this._message, allocate(intArrayFromString(address), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the subject for a message.
+ * @method getSubject
+ * @memberof! proton.Message#
+ * @returns {string} the subject of the Message.
+ */
+_Message_['getSubject'] = function() {
+    return Pointer_stringify(_pn_message_get_subject(this._message));
+};
+
+/**
+ * Set the subject of the Message.
+ * @method setSubject
+ * @memberof! proton.Message#
+ * @param {string} subject the subject we want to set for the Message.
+ */
+_Message_['setSubject'] = function(subject) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_subject(this._message, allocate(intArrayFromString(subject), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the reply to for a message.
+ * @method getReplyTo
+ * @memberof! proton.Message#
+ * @returns {string} the reply to of the Message.
+ */
+_Message_['getReplyTo'] = function() {
+    return Pointer_stringify(_pn_message_get_reply_to(this._message));
+};
+
+/**
+ * Set the reply to for a message.
+ * @method setReplyTo
+ * @memberof! proton.Message#
+ * @param {string} reply the reply to we want to set for the Message.
+ */
+_Message_['setReplyTo'] = function(reply) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_reply_to(this._message, allocate(intArrayFromString(reply), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the correlation id for a message.
+ * <p>
+ * A correlation id can be an a string, an unsigned long, a uuid or a binary value.
+ * @method getCorrelationID
+ * @memberof! proton.Message#
+ * @returns {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} the message id.
+ */
+_Message_['getCorrelationID'] = function() {
+    return this._correlationId['getObject']();
+};
+
+/**
+ * Set the correlation id for a message. See {@link proton.Message.getCorrelationID}
+ * for more details on the meaning of the correlation id. Note that only string,
+ * unsigned long, uuid, or binary values are permitted.
+ * @method setCorrelationID
+ * @memberof! proton.Message#
+ * @param {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} id the
+ *        new value of the correlation id.
+ */
+_Message_['setCorrelationID'] = function(id) {
+    this._correlationId['rewind']();
+    if (Data.isNumber(id)) {
+        this._correlationId['putULONG'](id);
+    } else {
+        this._correlationId['putObject'](id);
+    }
+};
+
+/**
+ * Get the content type for a message.
+ * @method getContentType
+ * @memberof! proton.Message#
+ * @returns {string} the content type of the Message.
+ */
+_Message_['getContentType'] = function() {
+    return Pointer_stringify(_pn_message_get_content_type(this._message));
+};
+
+/**
+ * Set the content type for a message.
+ * @method setContentType
+ * @memberof! proton.Message#
+ * @param {string} type the content type we want to set for the Message.
+ */
+_Message_['setContentType'] = function(type) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_content_type(this._message, allocate(intArrayFromString(type), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the content encoding for a message.
+ * @method getContentEncoding
+ * @memberof! proton.Message#
+ * @returns {string} the content encoding of the Message.
+ */
+_Message_['getContentEncoding'] = function() {
+    return Pointer_stringify(_pn_message_get_content_encoding(this._message));
+};
+
+/**
+ * Set the content encoding for a message.
+ * @method setContentEncoding
+ * @memberof! proton.Message#
+ * @param {string} encoding the content encoding we want to set for the Message.
+ */
+_Message_['setContentEncoding'] = function(encoding) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_content_encoding(this._message, allocate(intArrayFromString(encoding), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the expiry time for a message.
+ * A zero value for the expiry time indicates that the message will
+ * never expire. This is the default value.
+ * @method getExpiryTime
+ * @memberof! proton.Message#
+ * @returns {Date} the expiry time for the message.
+ */
+_Message_['getExpiryTime'] = function() {
+    // Getting the timestamp is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to hold
+    // the 64 bit number and Data.Long.toNumber() to convert it back into a
+    // JavaScript number.
+    var low =  _pn_message_get_expiry_time(this._message);
+    var high = Runtime.getTempRet0();
+    var long = new Data.Long(low, high);
+    long = long.toNumber();
+    return new Date(long);
+};
+
+/**
+ * Set the expiry time for a message.
+ * @method setExpiryTime
+ * @memberof! proton.Message#
+ * @param {(number|Date)} time the new expiry time for the message.
+ */
+_Message_['setExpiryTime'] = function(time) {
+    // Note that a timestamp is a 64 bit number so we have to use a proton.Data.Long.
+    var timestamp = Data.Long.fromNumber(time.valueOf());
+    this._check(_pn_message_set_expiry_time(this._message, timestamp.getLowBitsUnsigned(), timestamp.getHighBits()));
+};
+
+/**
+ * Get the creation time for a message.
+ * A zero value for the creation time indicates that the creation time
+ * has not been set. This is the default value.
+ * @method getCreationTime
+ * @memberof! proton.Message#
+ * @returns {Date} the creation time for the message.
+ */
+_Message_['getCreationTime'] = function() {
+    // Getting the timestamp is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to hold
+    // the 64 bit number and Data.Long.toNumber() to convert it back into a
+    // JavaScript number.
+    var low =  _pn_message_get_creation_time(this._message);
+    var high = Runtime.getTempRet0();
+    var long = new Data.Long(low, high);
+    long = long.toNumber();
+    return new Date(long);
+};
+
+/**
+ * Set the creation time for a message.
+ * @method setCreationTime
+ * @memberof! proton.Message#
+ * @param {(number|Date)} time the new creation time for the message.
+ */
+_Message_['setCreationTime'] = function(time) {
+    // Note that a timestamp is a 64 bit number so we have to use a proton.Data.Long.
+    var timestamp = Data.Long.fromNumber(time.valueOf());
+    this._check(_pn_message_set_creation_time(this._message, timestamp.getLowBitsUnsigned(), timestamp.getHighBits()));
+};
+
+/**
+ * Get the group id for a message.
+ * @method getGroupID
+ * @memberof! proton.Message#
+ * @returns {string} the group id of the Message.
+ */
+_Message_['getGroupID'] = function() {
+    return Pointer_stringify(_pn_message_get_group_id(this._message));
+};
+
+/**
+ * Set the group id for a message.
+ * @method setGroupID
+ * @memberof! proton.Message#
+ * @param {string} id the group id we want to set for the Message.
+ */
+_Message_['setGroupID'] = function(id) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_group_id(this._message, allocate(intArrayFromString(id), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Get the group sequence for a message.
+ * <p>
+ * The group sequence of a message identifies the relative ordering of
+ * messages within a group. The default value for the group sequence
+ * of a message is zero.
+ * @method getGroupSequence
+ * @memberof! proton.Message#
+ * @returns {number} the group sequence for the message.
+ */
+_Message_['getGroupSequence'] = function() {
+    return _pn_message_get_group_sequence(this._message);
+};
+
+/**
+ * Set the group sequence for a message. See {@link proton.Message.getGroupSequence}
+ * for details on what the group sequence means.
+ * @method setGroupSequence
+ * @memberof! proton.Message#
+ * @param {number} n the new group sequence for the message.
+ */
+_Message_['setGroupSequence'] = function(n) {
+    this._check(_pn_message_set_group_sequence(this._message, n));
+};
+
+/**
+ * Get the reply to group id for a message.
+ * @method getReplyToGroupID
+ * @memberof! proton.Message#
+ * @returns {string} the reply to group id of the Message.
+ */
+_Message_['getReplyToGroupID'] = function() {
+    return Pointer_stringify(_pn_message_get_reply_to_group_id(this._message));
+};
+
+/**
+ * Set the reply to group id for a message.
+ * @method setReplyToGroupID
+ * @memberof! proton.Message#
+ * @param {string} id the reply to group id we want to set for the Message.
+ */
+_Message_['setReplyToGroupID'] = function(id) {
+    var sp = Runtime.stackSave();
+    this._check(_pn_message_set_reply_to_group_id(this._message, allocate(intArrayFromString(id), 'i8', ALLOC_STACK)));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * The following methods are marked as deprecated and are not implemented.
+ * pn_message_get_format()
+ * pn_message_set_format()
+ * pn_message_load()
+ * pn_message_load_data()
+ * pn_message_load_text()
+ * pn_message_load_amqp()
+ * pn_message_load_json()
+ * pn_message_save()
+ * pn_message_save_data()
+ * pn_message_save_text()
+ * pn_message_save_amqp()
+ * pn_message_save_json()
+ * pn_message_data()
+ */
+
+/**
+ * Return a Binary representation of the message encoded in AMQP format. N.B. the
+ * returned {@link proton.Data.Binary} "owns" the underlying raw data and is thus
+ * responsible for freeing it or passing it to a method that consumes a Binary
+ * such as {@link proton.Message.decode}.
+ * @method encode
+ * @memberof! proton.Message#
+ * @returns {proton.Data.Binary} a representation of the message encoded in AMQP format.
+ */
+_Message_['encode'] = function() {
+    this._preEncode();
+    var size = 1024;
+    while (true) {
+        setValue(size, size, 'i32'); // Set pass by reference variable.
+        var bytes = _malloc(size);   // Allocate storage from emscripten heap.
+        var err = _pn_message_encode(this._message, bytes, size);
+        var size = getValue(size, 'i32'); // Dereference the real size value;
+
+        if (err === Module['Error']['OVERFLOW']) {
+            _free(bytes);
+            size *= 2;
+        } else if (err >= 0) {
+            return new Data['Binary'](size, bytes);
+        } else {
+            _free(bytes);
+            this._check(err);
+            return;
+        }
+    }
+};
+
+/**
+ * Decodes and loads the message content from supplied Binary AMQP data  N.B. 
+ * this method "consumes" data from a {@link proton.Data.Binary} in other words
+ * it takes responsibility for the underlying data and frees the raw data from
+ * the Binary.
+ * @method decode
+ * @memberof! proton.Message#
+ * @param {proton.Data.Binary} encoded the AMQP encoded binary message.
+ */
+_Message_['decode'] = function(encoded) {
+    var err = _pn_message_decode(this._message, encoded.start, encoded.size);
+    encoded['free'](); // Free the original Binary.
+    if (err >= 0) {
+        this._postDecode();
+    }
+    this._check(err);
+};
+
diff --git a/proton-c/bindings/javascript/messenger.js b/proton-c/bindings/javascript/messenger.js
new file mode 100644
index 0000000..e2f4418
--- /dev/null
+++ b/proton-c/bindings/javascript/messenger.js
@@ -0,0 +1,810 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                                 Messenger                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a proton.Messenger instance giving it an (optional) name. If name
+ * is supplied that will be used as the name of the Messenger, otherwise a UUID
+ * will be used. The Messenger is initialised to non-blocking mode as it makes
+ * little sense to have blocking behaviour in a JavaScript implementation.
+ * @classdesc The {@link proton.Messenger} class defines a high level interface for sending
+ * and receiving {@link proton.Message}. Every {@link proton.Messenger} contains a
+ * single logical queue of incoming messages and a single logical queue
+ * of outgoing messages. These messages in these queues may be destined
+ * for, or originate from, a variety of addresses.
+ * <p>
+ * The messenger interface is single-threaded.
+ * <pre>
+ * Address Syntax
+ * ==============
+ * </pre>
+ * An address has the following form:
+ * <pre>
+ *   [ amqp[s]:// ] [user[:password]@] domain [/[name]]
+ * </pre>
+ * Where domain can be one of:
+ * <pre>
+ *   host | host:port | ip | ip:port | name
+ * </pre>
+ * The following are valid examples of addresses:
+ * <pre>
+ *  - example.org
+ *  - example.org:1234
+ *  - amqp://example.org
+ *  - amqps://example.org
+ *  - example.org/incoming
+ *  - amqps://example.org/outgoing
+ *  - amqps://fred:trustno1@example.org
+ *  - 127.0.0.1:1234
+ *  - amqps://127.0.0.1:1234
+ *
+ * Sending & Receiving Messages
+ * ============================
+ * </pre>
+ * The {@link proton.Messenger} class works in conjuction with the {@link proton.Message} class.
+ * The {@link proton.Message} class is a mutable holder of message content.
+ * <p>
+ * The put method copies its Message to the outgoing queue, and may
+ * send queued messages if it can do so without blocking.  
+ * <pre>
+ *   var message = new proton.Message();
+ *   for (var i = 0; i < 3; i++) {
+ *      message.setAddress("amqp://host/queue");
+ *      message.setSubject = ("Hello World " + i);
+ *      messenger.put(message);
+ *   }
+ * </pre>
+ * Similarly, the recv method receives messages into the incoming
+ * queue. It may receive fewer than the requested number. The get method pops the
+ * eldest Message off the incoming queue and copies it into the Message
+ * object that you supply.
+ * <pre>
+ *   var message = new proton.Message();
+ *   messenger.recv(10);
+ *   while (messenger.incoming() > 0) {
+ *      messenger.get(message);
+ *      console.log(message.getSubject());
+ *   }
+ *   Hello World 0
+ *   Hello World 1
+ *   Hello World 2
+ * </pre>
+ *
+ * @constructor proton.Messenger
+ * @param {string} name the name of this Messenger instance.
+ */
+Module['Messenger'] = function(name) { // Messenger Constructor.
+    /**
+     * The emscripten idiom below is used in a number of places in the JavaScript
+     * bindings to map JavaScript Strings to C style strings. ALLOC_STACK will
+     * increase the stack and place the item there. When the stack is next restored
+     * (by calling Runtime.stackRestore()), that memory will be automatically
+     * freed. In C code compiled by emscripten saving and restoring of the stack
+     * is automatic, but if we want to us ALLOC_STACK from native JavaScript we
+     * need to explicitly save and restore the stack using Runtime.stackSave()
+     * and Runtime.stackRestore() or we will leak emscripten heap memory.
+     * See https://github.com/kripken/emscripten/wiki/Interacting-with-code
+     * The _pn_messenger constructor copies the char* passed to it.
+     */
+    var sp = Runtime.stackSave();
+    this._messenger = _pn_messenger(name ? allocate(intArrayFromString(name), 'i8', ALLOC_STACK) : 0);
+    Runtime.stackRestore(sp);
+
+    /**
+     * Initiate Messenger non-blocking mode. For JavaScript we make this the
+     * default behaviour and don't export this method because JavaScript is
+     * fundamentally an asynchronous non-blocking execution environment.
+     */
+    _pn_messenger_set_blocking(this._messenger, false);
+
+    // Subscriptions that haven't yet completed, used for managing subscribe events.
+    this._pendingSubscriptions = [];
+
+    // Used in the Event registration mechanism (in the 'on' and 'emit' methods).
+    this._callbacks = {};
+
+    // This call ensures that the emscripten network callback functions are initialised.
+    Module.EventDispatch.registerMessenger(this);
+};
+
+Module['Messenger'].PN_CUMULATIVE = 0x1; // Protected Class attribute.
+
+// Expose prototype as a variable to make method declarations less verbose.
+var _Messenger_ = Module['Messenger'].prototype;
+
+// ************************* Protected methods ********************************
+
+// We use the dot notation rather than associative array form for protected
+// methods so they are visible to this "package", but the Closure compiler will
+// minify and obfuscate names, effectively making a defacto "protected" method.
+
+/**
+ * This helper method checks the supplied error code, converts it into an
+ * exception and throws the exception. This method will try to use the message
+ * populated in pn_messenger_error(), if present, but if not it will fall
+ * back to using the basic error code rendering from pn_code().
+ * @param {number} code the error code to check.
+ */
+_Messenger_._check = function(code) {
+    if (code < 0 && code !== Module['Error']['INPROGRESS']) {
+        var errno = this['getErrno']();
+        var message = errno ? this['getError']() : Pointer_stringify(_pn_code(code));
+        if (message !== 'PN_TIMEOUT') {
+            if (this._callbacks['error']) {
+console.log("emitting " + message);
+                this._emit('error', new Module['MessengerError'](message));
+            } else {
+console.log("throwing " + message);
+                throw new Module['MessengerError'](message);
+            }
+        }
+    }
+
+    return code;
+};
+
+/**
+ * Invokes the callbacks registered for a specified event.
+ * @method _emit
+ * @memberof! proton.Messenger#
+ * @param event {string} the event we want to emit.
+ * @param param {object} the parameter we'd like to pass to the event callback.
+ */
+_Messenger_._emit = function(event, param) {
+    var callbacks = this._callbacks[event];
+    if (callbacks) {
+        for (var i = 0; i < callbacks.length; i++) {
+            var callback = callbacks[i];
+            if ('function' === typeof callback) {
+                callback.call(this, param);
+            }
+        }
+    }
+};
+
+/**
+ * Checks any pending subscriptions and when a source address becomes available
+ * emit a subscription event passing the Subscription that triggered the event.
+ * Note that this doesn't seem to work for listen/bind style subscriptions,
+ * that is to say subscriptions of the form amqp://~0.0.0.0, don't know why?
+ * As a workaround the subscribe call emits a subscription event immediately for
+ * peer subscriptions to the local Messenger, this *should* be OK.
+ */
+_Messenger_._checkSubscriptions = function() {
+    // Check for completed subscriptions, and emit subscribe event.
+    var subscriptions = this._pendingSubscriptions;
+    if (subscriptions.length) {
+        var pending = []; // Array of any subscriptions that remain pending.
+        for (var j = 0; j < subscriptions.length; j++) {
+            subscription = subscriptions[j];
+            if (subscription['getAddress']()) {
+                this._emit('subscription', subscription);
+            } else {
+                pending.push(subscription);
+            }
+        }
+        this._pendingSubscriptions = pending;
+    }
+};
+
+
+// *************************** Public methods *****************************
+
+/**
+ * N.B. The following methods are not exported by the JavaScript Messenger
+ * binding for reasons described below.
+ *
+ * For these methods it is expected that security would be implemented via
+ * a secure WebSocket. TODO what happens if we decide to implement TCP sockets
+ * via Node.js net library. If we do that we may want to compile OpenSSL
+ * using emscripten and include these methods.
+ * pn_messenger_set_certificate()
+ * pn_messenger_get_certificate()
+ * pn_messenger_set_private_key()
+ * pn_messenger_get_private_key()
+ * pn_messenger_set_password()
+ * pn_messenger_get_password()
+ * pn_messenger_set_trusted_certificates()
+ * pn_messenger_get_trusted_certificates()
+ *
+ * For these methods the implementation is fairly meaningless because JavaScript
+ * is a fundamentally asynchronous non-blocking environment.
+ * pn_messenger_set_timeout()
+ * pn_messenger_set_blocking()
+ * pn_messenger_interrupt()
+ * pn_messenger_send() // Not sure if this is useful in JavaScript.
+ */
+
+/**
+ * Registers a listener callback for a specified event.
+ * @method on
+ * @memberof! proton.Messenger#
+ * @param {string} event the event we want to listen for.
+ * @param {function} callback the callback function to be registered for the specified event.
+ */
+_Messenger_['on'] = function(event, callback) {
+    if ('function' === typeof callback) {
+        if (!this._callbacks[event]) {
+            this._callbacks[event] = [];
+        }
+
+        this._callbacks[event].push(callback);
+    }
+};
+
+/**
+ * Removes a listener callback for a specified event.
+ * @method removeListener
+ * @memberof! proton.Messenger#
+ * @param {string} event the event we want to detach from.
+ * @param {function} callback the callback function to be removed for the specified event.
+ *        if no callback is specified all callbacks are removed for the event.
+ */
+_Messenger_['removeListener'] = function(event, callback) {
+    if (callback) {
+        var callbacks = this._callbacks[event];
+        if ('function' === typeof callback && callbacks) {
+            // Search for the specified callback.
+            for (var i = 0; i < callbacks.length; i++) {
+                if (callback === callbacks[i]) {
+                    // If we find the specified callback, delete it and return.
+                    callbacks.splice(i, 1);
+                    return;
+                }
+            }
+        }
+    } else {
+        // If we call remove with no callback specified we remove all callbacks.
+        delete this._callbacks[event];
+    }
+};
+
+/**
+ * Retrieves the name of a Messenger.
+ * @method getName
+ * @memberof! proton.Messenger#
+ * @returns {string} the name of the messenger.
+ */
+_Messenger_['getName'] = function() {
+    return Pointer_stringify(_pn_messenger_name(this._messenger));
+};
+
+/**
+ * Retrieves the timeout for a Messenger.
+ * @method getTimeout
+ * @memberof! proton.Messenger#
+ * @returns {number} zero because JavaScript is fundamentally non-blocking.
+ */
+_Messenger_['getTimeout'] = function() {
+    return 0;
+};
+
+/**
+ * Accessor for messenger blocking mode.
+ * @method isBlocking
+ * @memberof! proton.Messenger#
+ * @returns {boolean} false because JavaScript is fundamentally non-blocking.
+ */
+_Messenger_['isBlocking'] = function() {
+    return false;
+};
+
+/**
+ * Free the Messenger. This will close all connections that are managed
+ * by the Messenger. Call the stop method before destroying the Messenger.
+ * <p>
+ * N.B. This method has to be called explicitly in JavaScript as we can't
+ * intercept finalisers, so we need to remember to free before removing refs.
+ * @method free
+ * @memberof! proton.Messenger#
+ */
+_Messenger_['free'] = function() {
+    // This call ensures that the emscripten network callback functions are removed.
+    Module.EventDispatch.unregisterMessenger(this);
+    _pn_messenger_free(this._messenger);
+};
+
+/**
+ * @method getErrno
+ * @memberof! proton.Messenger#
+ * @returns {number} the most recent error message code.
+ */
+_Messenger_['getErrno'] = function() {
+    return _pn_messenger_errno(this._messenger);
+};
+
+/**
+ * @method getError
+ * @memberof! proton.Messenger#
+ * @returns {string} the most recent error message as a String.
+ */
+_Messenger_['getError'] = function() {
+    return Pointer_stringify(_pn_error_text(_pn_messenger_error(this._messenger)));
+};
+
+/**
+ * Returns the size of the outgoing window that was set with setOutgoingWindow.
+ * The default is 0.
+ * @method getOutgoingWindow
+ * @memberof! proton.Messenger#
+ * @returns {number} the outgoing window size.
+ */
+_Messenger_['getOutgoingWindow'] = function() {
+    return _pn_messenger_get_outgoing_window(this._messenger);
+};
+
+/**
+ * Sets the outgoing tracking window for the Messenger. The Messenger will
+ * track the remote status of this many outgoing deliveries after calling
+ * send. Defaults to zero.
+ * <p>
+ * A Message enters this window when you call put() with the Message.
+ * If your outgoing window size is n, and you call put() n+1 times, status
+ * information will no longer be available for the first Message.
+ * @method setOutgoingWindow
+ * @memberof! proton.Messenger#
+ * @param {number} window the size of the tracking window in messages.
+ */
+_Messenger_['setOutgoingWindow'] = function(window) {
+    _pn_messenger_set_outgoing_window(this._messenger, window);
+};
+
+/**
+ * Returns the size of the incoming window that was set with setIncomingWindow.
+ * The default is 0.
+ * @method getIncomingWindow
+ * @memberof! proton.Messenger#
+ * @returns {number} the incoming window size.
+ */
+_Messenger_['getIncomingWindow'] = function() {
+    return _pn_messenger_get_incoming_window(this._messenger);
+};
+
+/**
+ * Sets the incoming tracking window for the Messenger. The Messenger will
+ * track the remote status of this many incoming deliveries after calling
+ * send. Defaults to zero.
+ * <p>
+ * Messages enter this window only when you take them into your application
+ * using get(). If your incoming window size is n, and you get() n+1 messages
+ * without explicitly accepting or rejecting the oldest message, then the
+ * Message that passes beyond the edge of the incoming window will be assigned
+ * the default disposition of its link.
+ * @method setIncomingWindow
+ * @memberof! proton.Messenger#
+ * @param {number} window the size of the tracking window in messages.
+ */
+_Messenger_['setIncomingWindow'] = function(window) {
+    _pn_messenger_set_incoming_window(this._messenger, window);
+};
+
+/**
+ * Currently a no-op placeholder. For future compatibility, do not send or
+ * recv messages before starting the Messenger.
+ * @method start
+ * @memberof! proton.Messenger#
+ */
+_Messenger_['start'] = function() {
+    this._check(_pn_messenger_start(this._messenger));
+};
+
+/**
+ * Transitions the Messenger to an inactive state. An inactive Messenger
+ * will not send or receive messages from its internal queues. A Messenger
+ * should be stopped before being discarded to ensure a clean shutdown
+ * handshake occurs on any internally managed connections.
+ * <p>
+ * The Messenger may require some time to stop if it is busy, and in that
+ * case will return {@link proton.Error.INPROGRESS}. In that case, call isStopped
+ * to see if it has fully stopped.
+ * @method stop
+ * @memberof! proton.Messenger#
+ */
+_Messenger_['stop'] = function() {
+    _pn_messenger_stop(this._messenger);
+};
+
+/**
+ * Returns true iff a Messenger is in the stopped state.
+ * @method isStopped
+ * @memberof! proton.Messenger#
+ * @returns {boolean} true iff a Messenger is in the stopped state.
+ */
+_Messenger_['isStopped'] = function() {
+    return (_pn_messenger_stopped(this._messenger) > 0);
+};
+
+/**
+ * Subscribes the Messenger to messages originating from the
+ * specified source. The source is an address as specified in the
+ * Messenger introduction with the following addition. If the
+ * domain portion of the address begins with the '~' character, the
+ * Messenger will interpret the domain as host/port, bind to it,
+ * and listen for incoming messages. For example "~0.0.0.0",
+ * "amqp://~0.0.0.0", and "amqps://~0.0.0.0" will all bind to any
+ * local interface and listen for incoming messages with the last
+ * variant only permitting incoming SSL connections.
+ * @method subscribe
+ * @memberof! proton.Messenger#
+ * @param {string} source the source address we're subscribing to.
+ * @returns {Subscription} a subscription.
+ */
+_Messenger_['subscribe'] = function(source) {
+    if (!source) {
+        this._emit('error', new Module['SubscriptionError'](source, 'CONNECTION ERROR: Address not specified'));
+    } else {
+        return Module.EventDispatch.subscribe(this, source);
+    }
+};
+
+/**
+ * Places the content contained in the message onto the outgoing queue
+ * of the Messenger. This method will never block, however it will send any
+ * unblocked Messages in the outgoing queue immediately and leave any blocked
+ * Messages remaining in the outgoing queue. The outgoing property may be
+ * used to check the depth of the outgoing queue.
+ * <p>
+ * When the content in a given Message object is copied to the outgoing
+ * message queue, you may then modify or discard the Message object
+ * without having any impact on the content in the outgoing queue.
+ * <p>
+ * This method returns an outgoing tracker for the Message.  The tracker
+ * can be used to determine the delivery status of the Message.
+ * @method put
+ * @memberof! proton.Messenger#
+ * @param {proton.Message} message a Message to send.
+ * @param {boolean} flush if this is set true or is undefined then messages are
+ *        flushed (this is the default). If explicitly set to false then messages
+ *        may not be sent immediately and might require an explicit call to work().
+ *        This may be used to "batch up" messages and *may* be more efficient.
+ * @returns {proton.Data.Long} a tracker.
+ */
+_Messenger_['put'] = function(message, flush) {
+    flush = flush === false ? false : true; // Defaults to true if not explicitly specified.
+    message._preEncode();
+    this._check(_pn_messenger_put(this._messenger, message._message));
+
+    if (flush) {
+        Module.EventDispatch.flush();
+    }
+
+    // Getting the tracker is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
+    // low/high pair around to methods that require a tracker.
+    var low = _pn_messenger_outgoing_tracker(this._messenger);
+    var high = Runtime.getTempRet0();
+    return new Data.Long(low, high);
+};
+
+/**
+ * Gets the last known remote state of the delivery associated with the given tracker.
+ * @method status
+ * @memberof! proton.Messenger#
+ * @param {proton.Data.Long} tracker the tracker whose status is to be retrieved.
+ * @returns {proton.Status} one of None, PENDING, REJECTED, or ACCEPTED.
+ */
+_Messenger_['status'] = function(tracker) {
+    if (tracker == null) { // Use == not === to check for both null and undefined.
+        var low = _pn_messenger_outgoing_tracker(this._messenger);
+        var high = Runtime.getTempRet0();
+        tracker = new Data.Long(low, high);
+    }
+
+    return _pn_messenger_status(this._messenger, tracker.getLowBitsUnsigned(), tracker.getHighBits());
+};
+
+/**
+ * Checks if the delivery associated with the given tracker is still waiting to be sent.
+ * @method isBuffered
+ * @memberof! proton.Messenger#
+ * @param {proton.Data.Long} tracker the tracker identifying the delivery.
+ * @returns {boolean} true if delivery is still buffered.
+ */
+_Messenger_['isBuffered'] = function(tracker) {
+    if (tracker == null) { // Use == not === to check for both null and undefined.
+        var low = _pn_messenger_outgoing_tracker(this._messenger);
+        var high = Runtime.getTempRet0();
+        tracker = new Data.Long(low, high);
+    }
+
+    return (_pn_messenger_buffered(this._messenger, tracker.getLowBitsUnsigned(), tracker.getHighBits()) > 0);
+};
+
+/**
+ * Frees a Messenger from tracking the status associated with a given tracker.
+ * If you don't supply a tracker, all outgoing messages up to the most recent
+ * will be settled.
+ * @method settle
+ * @memberof! proton.Messenger#
+ * @param {proton.Data.Long} tracker the tracker identifying the delivery.
+ */
+_Messenger_['settle'] = function(tracker) {
+    // Getting the tracker is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
+    // low/high pair around to methods that require a tracker.
+    var flags = 0;
+    if (tracker == null) { // Use == not === to check for both null and undefined.
+        var low = _pn_messenger_outgoing_tracker(this._messenger);
+        var high = Runtime.getTempRet0();
+        tracker = new Data.Long(low, high);
+        flags = Module['Messenger'].PN_CUMULATIVE;
+    }
+
+    _pn_messenger_settle(this._messenger, tracker.getLowBitsUnsigned(), tracker.getHighBits(), flags);
+};
+
+/**
+ * Sends or receives any outstanding messages queued for a Messenger.
+ * For JavaScript the only timeout that makes sense is 0 (do not block).
+ * This method may also do I/O work other than sending and receiving messages.
+ * For example, closing connections after messenger.stop() has been called.
+ * @method work
+ * @memberof! proton.Messenger#
+ * @returns {boolean} true if there is work still to do, false otherwise.
+ */
+_Messenger_['work'] = function() {
+    return (this._check(_pn_messenger_work(this._messenger, 0)) > 0);
+};
+
+/**
+ * Receives up to limit messages into the incoming queue.  If no value for limit
+ * is supplied, this call will receive as many messages as it can buffer internally.
+ * @method recv
+ * @memberof! proton.Messenger#
+ * @param {number} limit the maximum number of messages to receive or -1 to to receive
+ *        as many messages as it can buffer internally.
+ */
+_Messenger_['recv'] = function(limit) {
+    _pn_messenger_recv(this._messenger, (limit ? limit : -1));
+};
+
+/**
+ * Returns the capacity of the incoming message queue of messenger. Note this
+ * count does not include those messages already available on the incoming queue.
+ * @method receiving
+ * @memberof! proton.Messenger#
+ * @returns {number} the message queue capacity.
+ */
+_Messenger_['receiving'] = function() {
+    return _pn_messenger_receiving(this._messenger);
+};
+
+/**
+ * Moves the message from the head of the incoming message queue into the
+ * supplied message object. Any content in the message will be overwritten.
+ * <p>
+ * A tracker for the incoming Message is returned. The tracker can later be
+ * used to communicate your acceptance or rejection of the Message.
+ * @method get
+ * @memberof! proton.Messenger#
+ * @param {proton.Message} message the destination message object. If no Message
+ *        object is supplied, the Message popped from the head of the queue is discarded.
+ * @param {boolean} decodeBinaryAsString if set decode any AMQP Binary payload
+ *        objects as strings. This can be useful as the data in Binary objects
+ *        will be overwritten with subsequent calls to get, so they must be
+ *        explicitly copied. Needless to say it is only safe to set this flag if
+ *        you know that the data you are dealing with is actually a string, for
+ *        example C/C++ applications often seem to encode strings as AMQP binary,
+ *        a common cause of interoperability problems.
+ * @returns {proton.Data.Long} a tracker for the incoming Message.
+ */
+_Messenger_['get'] = function(message, decodeBinaryAsString) {
+    var impl = null;
+    if (message) {
+        impl = message._message;
+    }
+
+    _pn_messenger_get(this._messenger, impl);
+
+    if (message) {
+        message._postDecode(decodeBinaryAsString);
+    }
+
+    // Getting the tracker is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
+    // low/high pair around to methods that require a tracker.
+    var low = _pn_messenger_incoming_tracker(this._messenger);
+    var high = Runtime.getTempRet0();
+    return new Data.Long(low, high);
+};
+
+/**
+ * Returns the Subscription of the Message returned by the most recent call
+ * to get, or null if pn_messenger_get has not yet been called.
+ * @method incomingSubscription
+ * @memberof! proton.Messenger#
+ * @returns {Subscription} a Subscription or null if get has never been called
+ *          for this Messenger.
+ */
+_Messenger_['incomingSubscription'] = function() {
+    var subscription = _pn_messenger_incoming_subscription(this._messenger);
+    if (subscription) {
+        return new Subscription(subscription);
+    } else {
+        return null;
+    }
+};
+
+/**
+ * Signal the sender that you have acted on the Message pointed to by the tracker.
+ * If no tracker is supplied, then all messages that have been returned by the
+ * get method are accepted, except those that have already been auto-settled
+ * by passing beyond your incoming window size.
+ * @method accept
+ * @memberof! proton.Messenger#
+ * @param {proton.Data.Long} tracker the tracker identifying the delivery.
+ */
+_Messenger_['accept'] = function(tracker) {
+    // Getting the tracker is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
+    // low/high pair around to methods that require a tracker.
+    var flags = 0;
+    if (tracker == null) { // Use == not === to check for both null and undefined.
+        var low = _pn_messenger_incoming_tracker(this._messenger);
+        var high = Runtime.getTempRet0();
+        tracker = new Data.Long(low, high);
+        flags = Module['Messenger'].PN_CUMULATIVE;
+    }
+
+    this._check(_pn_messenger_accept(this._messenger, tracker.getLowBitsUnsigned(), tracker.getHighBits(), flags));
+};
+
+/**
+ * Rejects the Message indicated by the tracker.  If no tracker is supplied,
+ * all messages that have been returned by the get method are rejected, except
+ * those already auto-settled by passing beyond your outgoing window size.
+ * @method reject
+ * @memberof! proton.Messenger#
+ * @param {proton.Data.Long} tracker the tracker identifying the delivery.
+ */
+_Messenger_['reject'] = function(tracker) {
+    // Getting the tracker is a little tricky as it is a 64 bit number. The way
+    // emscripten handles this is to return the low 32 bits directly and pass
+    // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
+    // low/high pair around to methods that require a tracker.
+    var flags = 0;
+    if (tracker == null) { // Use == not === to check for both null and undefined.
+        var low = _pn_messenger_incoming_tracker(this._messenger);
+        var high = Runtime.getTempRet0();
+        tracker = new Data.Long(low, high);
+        flags = Module['Messenger'].PN_CUMULATIVE;
+    }
+
+    this._check(_pn_messenger_reject(this._messenger, tracker.getLowBitsUnsigned(), tracker.getHighBits(), flags));
+};
+
+/**
+ * Returns the number of messages in the outgoing message queue of a messenger.
+ * @method outgoing
+ * @memberof! proton.Messenger#
+ * @returns {number} the outgoing queue depth.
+ */
+_Messenger_['outgoing'] = function() {
+    return _pn_messenger_outgoing(this._messenger);
+};
+
+/**
+ * Returns the number of messages in the incoming message queue of a messenger.
+ * @method incoming
+ * @memberof! proton.Messenger#
+ * @returns {number} the incoming queue depth.
+ */
+_Messenger_['incoming'] = function() {
+    return _pn_messenger_incoming(this._messenger);
+};
+
+/**
+ * Adds a routing rule to a Messenger's internal routing table.
+ * <p>
+ * The route method may be used to influence how a messenger will internally treat
+ * a given address or class of addresses. Every call to the route method will
+ * result in messenger appending a routing rule to its internal routing table.
+ * <p>
+ * Whenever a message is presented to a messenger for delivery, it will match the
+ * address of this message against the set of routing rules in order. The first
+ * rule to match will be triggered, and instead of routing based on the address
+ * presented in the message, the messenger will route based on the address supplied
+ * in the rule.
+ * <p>
+ * The pattern matching syntax supports two types of matches, a '' will match any
+ * character except a '/', and a '*' will match any character including a '/'.
+ * <p>
+ * A routing address is specified as a normal AMQP address, however it may
+ * additionally use substitution variables from the pattern match that triggered
+ * the rule.
+ * <p>
+ * Any message sent to "foo" will be routed to "amqp://foo.com":
+ * <pre>
+ * route("foo", "amqp://foo.com");
+ * </pre>
+ * Any message sent to "foobar" will be routed to "amqp://foo.com/bar":
+ * <pre>
+ * route("foobar", "amqp://foo.com/bar");
+ * </pre>
+ * Any message sent to bar/<path> will be routed to the corresponding path within
+ * the amqp://bar.com domain:
+ * <pre>
+ * route("bar/*", "amqp://bar.com/$1");
+ * </pre>
+ * Supply credentials for foo.com:
+ * <pre>
+ * route("amqp://foo.com/*", "amqp://user:password@foo.com/$1");
+ * </pre>
+ * Supply credentials for all domains:
+ * <pre>
+ * route("amqp://*", "amqp://user:password@$1");
+ * </pre>
+ * Route all addresses through a single proxy while preserving the original destination:
+ * <pre>
+ * route("amqp://%/*", "amqp://user:password@proxy/$1/$2");
+ * </pre>
+ * Route any address through a single broker:
+ * <pre>
+ * route("*", "amqp://user:password@broker/$1");
+ * </pre>
+ * @method route
+ * @memberof! proton.Messenger#
+ * @param {string} pattern a glob pattern to select messages.
+ * @param {string} address an address indicating outgoing address rewrite.
+ */
+_Messenger_['route'] = function(pattern, address) {
+    var sp = Runtime.stackSave();
+    _pn_messenger_route(this._messenger,
+                        allocate(intArrayFromString(pattern), 'i8', ALLOC_STACK),
+                        allocate(intArrayFromString(address), 'i8', ALLOC_STACK));
+    Runtime.stackRestore(sp);
+};
+
+/**
+ * Rewrite message addresses prior to transmission.
+ * <p>
+ * Similar to route(), except that the destination of the Message is determined
+ * before the message address is rewritten.
+ * <p>
+ * The outgoing address is only rewritten after routing has been finalized. If
+ * a message has an outgoing address of "amqp://0.0.0.0:5678", and a rewriting
+ * rule that changes its outgoing address to "foo", it will still arrive at the
+ * peer that is listening on "amqp://0.0.0.0:5678", but when it arrives there,
+ * the receiver will see its outgoing address as "foo".
+ * <p>
+ * The default rewrite rule removes username and password from addresses
+ * before they are transmitted.
+ * @method rewrite
+ * @memberof! proton.Messenger#
+ * @param {string} pattern a glob pattern to select messages.
+ * @param {string} address an address indicating outgoing address rewrite.
+ */
+_Messenger_['rewrite'] = function(pattern, address) {
+    var sp = Runtime.stackSave();
+    _pn_messenger_rewrite(this._messenger,
+                          allocate(intArrayFromString(pattern), 'i8', ALLOC_STACK),
+                          allocate(intArrayFromString(address), 'i8', ALLOC_STACK));
+    Runtime.stackRestore(sp);
+};
+
diff --git a/proton-c/bindings/javascript/module.js b/proton-c/bindings/javascript/module.js
new file mode 100644
index 0000000..b755f59
--- /dev/null
+++ b/proton-c/bindings/javascript/module.js
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * This file defines the Module Object which provides a namespace around the Proton
+ * Messenger API. The Module object is used extensively by the emscripten runtime,
+ * however for convenience it is exported with the name "proton" and not "Module".
+ * <p>
+ * The emscripten compiled proton-c code and the JavaScript binding code will be 
+ * minified by the Closure compiler, so all comments will be stripped from the
+ * actual library.
+ * <p>
+ * This JavaScript wrapper provides a somewhat more idiomatic object oriented
+ * interface which abstracts the low-level emscripten based implementation details
+ * from client code. Any similarities to the Proton Python binding are deliberate.
+ * @file
+ */
+
+/**
+ * The Module Object is exported by emscripten for all execution platforms, we
+ * use it as a namespace to allow us to selectively export only what we wish to
+ * be publicly visible from this package/module, which is wrapped in a closure.
+ * <p>
+ * Internally the binding code uses the associative array form for declaring
+ * exported properties to prevent the Closure compiler from minifying e.g.
+ * <pre>Module['Messenger'] = ...</pre>
+ * Exported Objects can however be used in client code using a more convenient
+ * and obvious proton namespace, e.g.:
+ * <pre>
+ * var proton = require('qpid-proton');
+ * var messenger = new proton.Messenger();
+ * var message = new proton.Message();
+ * ...
+ * </pre>
+ * The core part of this library is actually proton-c compiled into JavaScript.
+ * In order to provide C style memory management (malloc/free) emscripten uses
+ * a "virtual heap", which is actually a pre-allocated ArrayBuffer. The size of
+ * this virtual heap is set as part of the runtime initialisation and cannot be
+ * changed subsequently (the default size is 16*1024*1024 = 16777216).
+ * <p>
+ * Applications can specify the size of virtual heap that they require via the
+ * global variable PROTON_TOTAL_MEMORY, this must be set <b>before</b> the library is
+ * loaded e.g. in Node.js an application would do:
+ * <pre>
+ * PROTON_TOTAL_MEMORY = 50000000; // Note no var - it needs to be global.
+ * var proton = require('qpid-proton');
+ * ...
+ * </pre>
+ * A browser based application would do:
+ * <pre>
+ * &lt;script type="text/javascript"&gt;PROTON_TOTAL_MEMORY = 50000000;&lt;/script&gt;
+ * &lt;script type="text/javascript" src="proton.js">&lt;/script&gt;
+ * </pre>
+ * If the global variable PROTON_TOTAL_MEMORY has been set by the application this
+ * will result in the emscripten heap getting set to the next multiple of
+ * 16777216 above PROTON_TOTAL_MEMORY.
+ * <p>
+ * The global variable PROTON_TOTAL_STACK may be used in a similar way to increase
+ * the stack size from its default of 5*1024*1024 = 5242880. It is worth noting
+ * that Strings are allocated on the stack, so you may need this if you end up
+ * wanting to send very large strings.
+ * @namespace proton
+ */
+var Module = {};
+
+if (typeof global === 'object') { // If Node.js
+    if (global['PROTON_TOTAL_MEMORY']) {
+        Module['TOTAL_MEMORY'] = global['PROTON_TOTAL_MEMORY'];
+    }
+    if (global['PROTON_TOTAL_STACK']) {
+        Module['TOTAL_STACK'] = global['PROTON_TOTAL_STACK'];
+    }
+} else if (typeof window === 'object') { // If browser
+    if (window['PROTON_TOTAL_MEMORY']) {
+        Module['TOTAL_MEMORY'] = window['PROTON_TOTAL_MEMORY'];
+    }
+    if (window['PROTON_TOTAL_STACK']) {
+        Module['TOTAL_STACK'] = window['PROTON_TOTAL_STACK'];
+    }
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*                               EventDispatch                               */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * EventDispatch is a Singleton class that allows callbacks to be registered,
+ * which will get triggered by the emscripten WebSocket network callbacks.
+ * Clients of Messenger will register callbacks by calling:
+ * <pre>
+ * messenger.on('error', &lt;callback function&gt;);
+ * messenger.on('work', &lt;callback function&gt;);
+ * messenger.on('subscription', &lt;callback function&gt;);
+ * </pre>
+ * EventDispatch supports callback registration from multiple Messenger instances.
+ * The client callbacks will actually be called when a given messenger has work
+ * available or a WebSocket close has been occurred.
+ * <p>
+ * The approach implemented here allows the registered callbacks to follow a
+ * similar pattern to _process_incoming and _process_outgoing in async.py
+ * @constructor proton.EventDispatch
+ */
+Module.EventDispatch = new function() { // Note the use of new to create a Singleton.
+    var POLLIN  = 0x001;
+    var POLLOUT = 0x004;
+    var _error = null;
+    var _messengers = {};  // Keyed by name.
+    var _selectables = {}; // Keyed by file descriptor.
+
+    var _initialise = function() {
+        /**
+         * Initialises the emscripten network callback functions. This needs
+         * to be done the first time we call registerMessenger rather than
+         * when we create the Singleton because emscripten's socket filesystem
+         * has to be mounted before can listen for any of these events.
+         */
+        Module['websocket']['on']('open', _pump);
+        Module['websocket']['on']('connection', _pump);
+        Module['websocket']['on']('message', _pump);
+        Module['websocket']['on']('close', _closeHandler);
+        Module['websocket']['on']('error', _errorHandler);
+
+        /**
+         * For Node.js the network code uses the ws WebSocket library, see
+         * https://github.com/einaros/ws. The following is a "Monkey Patch"
+         * that fixes a problem with Receiver.js where it wasn't checking if
+         * an Object was null before accessing its properties, so it was
+         * possible to see errors like:
+         * TypeError: Cannot read property 'fragmentedOperation' of null
+         * at Receiver.endPacket (.....node_modules/ws/lib/Receiver.js:224:18)
+         * This problem is generally seen in Server code after messenger.stop()
+         * I *think* that the underlying issue is actually because ws calls
+         * cleanup directly rather than pushing it onto the event loop so the
+         * this.state stuff gets cleared before the endPacket method is called.
+         * This fix simply interposes a check to avoid calling endPacket if
+         * the state has been cleared (i.e. the WebSocket has been closed).
+         */
+        if (ENVIRONMENT_IS_NODE) {
+            try {
+                var ws = require('ws');
+                // Array notation to stop Closure compiler minifying properties we need.
+                ws['Receiver'].prototype['originalEndPacket'] = ws['Receiver'].prototype['endPacket'];
+                ws['Receiver'].prototype['endPacket'] = function() {
+                    if (this['state']) {
+                        this['originalEndPacket']();
+                    }
+                };
+            } catch (e) {
+                console.error("Failed to apply Monkey Patch to ws WebSocket library");
+            }
+        }
+
+        _initialise = function() {}; // After first call replace with null function.
+    };
+
+    /**
+     * Messenger error handling can be a bit inconsistent and in several places
+     * rather than returning an error code or setting an error it simply writes
+     * to fprintf. This is something of a Monkey Patch that replaces the emscripten
+     * library fprintf call with one that checks the message and sets a variable
+     * if the message is an ERROR. TODO At some point hopefully Dominic Evans'
+     * patch on Jira PROTON-571 will render this code redundant.
+     */
+    _fprintf = function(stream, format, varargs) {
+        var array = __formatString(format, varargs);
+        array.pop(); // Remove the trailing \n
+        var string = intArrayToString(array); // Convert to native JavaScript string.
+        if (string.indexOf('ERROR') === -1) { // If not an ERROR just log the message.
+            console.log(string);
+        } else {
+            _error = string;
+        }
+    };
+
+    /**
+     * This method iterates through all registered Messengers and retrieves any
+     * pending selectables, which are stored in a _selectables map keyed by fd.
+     */
+    var _updateSelectables = function() {
+        var sel = 0;
+        var fd = -1;
+        for (var name in _messengers) {
+            var messenger = _messengers[name];
+            while ((sel = _pn_messenger_selectable(messenger._messenger))) {
+                fd = _pn_selectable_fd(sel);
+                // Only register valid selectables, otherwise free them.
+                if (fd === -1) {
+                    _pn_selectable_free(sel);
+                } else {
+                    _selectables[fd] = {messenger: messenger, selectable: sel};
+                }
+            }
+        }
+        return fd; // Return the most recently added selector's file descriptor.
+    };
+
+    /**
+     * Continually pump data while there's still work to do.
+     */
+    var _pump = function() {
+        while (_pumpOnce());
+    };
+
+    /**
+     * This method more or less follows the pattern of the pump_once method from
+     * class Pump in tests/python/proton_tests/messenger.py. It looks a little
+     * different because the select/poll implemented here uses some low-level
+     * emscripten internals (stream = FS.getStream(fd), sock = stream.node.sock,
+     * mask = sock.sock_ops.poll(sock)). We use the internals so we don't have
+     * to massage from file descriptors into the C style poll interface.
+     */
+    var _pumpOnce = function() {
+        _updateSelectables();
+
+        var count = 0;
+        for (var fd in _selectables) {
+            var selectable = _selectables[fd];
+            var sel = selectable.selectable;
+            var terminal = _pn_selectable_is_terminal(sel);
+            if (terminal) {
+                _pn_selectable_free(sel);
+                delete _selectables[fd];
+            } else {
+                var stream = FS.getStream(fd);
+                if (stream) {
+                    var sock = stream.node.sock;
+                    if (sock.sock_ops.poll) {
+                        var mask = sock.sock_ops.poll(sock); // Low-level poll call.
+                        if (mask) {
+                            var messenger = selectable.messenger;
+                            var capacity = _pn_selectable_capacity(sel) > 0;
+                            var pending = _pn_selectable_pending(sel) > 0;
+
+                            if ((mask & POLLIN) && capacity) {
+//console.log("- readable fd = " + fd + ", capacity = " + _pn_selectable_capacity(sel));
+                                _error = null; // May get set by _pn_selectable_readable.
+                                _pn_selectable_readable(sel);
+                                count++; // Should this be inside the test for _error? Don't know.
+                                var errno = messenger['getErrno']();
+                                _error = errno ? messenger['getError']() : _error;
+                                if (_error) {
+                                    _errorHandler([fd, 0, _error]);
+                                } else {
+                                    // Don't send work event if it's a listen socket.
+                                    if (!sock.server) {
+                                        messenger._checkSubscriptions();
+                                        messenger._emit('work');
+                                    }
+                                }
+                            }
+                            if ((mask & POLLOUT) && pending) {
+//console.log("- writeable fd = " + fd + ", pending = " + _pn_selectable_pending(sel));
+                                _pn_selectable_writable(sel);
+                                //TODO looks like this block isn't needed. Need to
+                                //check with a test-case that writes data as fast as
+                                //it can. If not needed then delete.
+                                /*
+                                count++;
+                                // Check _selectables again in case the call to
+                                // _pn_selectable_writable caused a socket close.
+                                if (_selectables[fd]) {
+                                    messenger._checkSubscriptions();
+                                    messenger._emit('work');
+                                }
+                                */
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return count;
+    };
+
+    /**
+     * Handler for the emscripten socket close event.
+     */
+    var _closeHandler = function(fd) {
+        var selectable = _selectables[fd];
+        if (selectable) {
+            // Close and remove the selectable.
+            var sel = selectable.selectable;
+            _pn_selectable_free(sel); // This closes the underlying socket too.
+            delete _selectables[fd];
+
+            var messenger = selectable.messenger;
+            messenger._emit('work');
+        }
+    };
+
+    /**
+     * Handler for the emscripten socket error event.
+     */
+    var _errorHandler = function(error) {
+        var fd = error[0];
+        var message = error[2];
+
+        _updateSelectables();
+
+        var selectable = _selectables[fd];
+        if (selectable) {
+            // Close and remove the selectable.
+            var sel = selectable.selectable;
+            _pn_selectable_free(sel); // This closes the underlying socket too.
+            delete _selectables[fd];
+
+            var messenger = selectable.messenger;
+
+            // Remove any pending Subscriptions whose fd matches the error fd.
+            var subscriptions = messenger._pendingSubscriptions;
+            for (var i = 0; i < subscriptions.length; i++) {
+                subscription = subscriptions[i];
+                // Use == not === as we don't care if fd is a number or a string.
+                if (subscription.fd == fd) {
+                    messenger._pendingSubscriptions.splice(i, 1);
+                    if (message.indexOf('EHOSTUNREACH:') === 0) {
+                        message = 'CONNECTION ERROR (' + subscription.source + '): bind: Address already in use';
+                    }
+                    messenger._emit('error', new Module['SubscriptionError'](subscription.source, message));
+                    return;
+                }
+            }
+
+            messenger._emit('error', new Module['MessengerError'](message));
+        }
+    };
+
+    /**
+     * Flush any data that has been written by the Messenger put() method.
+     * @method flush
+     */
+    this.flush = function() {
+        _pump();
+    };
+
+    /**
+     * Subscribe to a specified source address.
+     * <p>
+     * This method is delegated to by the subscribe method of {@link proton.Messenger}.
+     * We delegate to EventDispatch because we create Subscription objects that
+     * contain some additional information (such as file descriptors) which are
+     * only available to EventDispatch and we don't really want to expose to the
+     * wider API. This low-level information is mainly used for error handling
+     * which is itself encapsulated in EventDispatch.
+     * @method subscribe
+     * @memberof! proton.EventDispatch#
+     * @param {proton.Messenger} messenger the Messenger instance that this
+     *        subscription relates to.
+     * @param {string} source the address that we'd like to subscribe to.
+     */
+    this.subscribe = function(messenger, source) {
+        // First update selectables before subscribing so we can work out the
+        // Subscription fd (which will be the listen file descriptor).
+        _updateSelectables();
+        var sp = Runtime.stackSave();
+        var subscription = _pn_messenger_subscribe(messenger._messenger,
+                                                   allocate(intArrayFromString(source), 'i8', ALLOC_STACK));
+        Runtime.stackRestore(sp);
+        var fd = _updateSelectables();
+
+        subscription = new Subscription(subscription, source, fd);
+        messenger._pendingSubscriptions.push(subscription);
+
+        // For passive subscriptions emit a subscription event (almost) immediately,
+        // otherwise defer until the address has been resolved remotely.
+        if (subscription.passive) {
+            // We briefly delay the call to checkSubscriptions because it is possible
+            // for passive subscriptions to fail if another process is bound to the
+            // port specified in the subscription.
+            var check = function() {messenger._checkSubscriptions();};
+            setTimeout(check, 10);
+        }
+
+        return subscription;
+    };
+
+    /**
+     * Register the specified Messenger as being interested in network events.
+     * @method registerMessenger
+     * @memberof! proton.EventDispatch#
+     * @param {proton.Messenger} messenger the Messenger instance we want to
+     *        register to receive network events.
+     */
+    this.registerMessenger = function(messenger) {
+        _initialise();
+
+        var name = messenger['getName']();
+        _messengers[name] = messenger;
+
+        // Set the Messenger "passive" as we are supplying our own event loop here.
+        _pn_messenger_set_passive(messenger._messenger, true);
+    };
+
+    /**
+     * Unregister the specified Messenger from interest in network events.
+     * @method unregisterMessenger
+     * @memberof! proton.EventDispatch#
+     * @param {proton.Messenger} messenger the Messenger instance we want to
+     *        unregister from receiving network events.
+     */
+    this.unregisterMessenger = function(messenger) {
+        var name = messenger['getName']();
+        delete _messengers[name];
+    };
+};
+
diff --git a/proton-c/bindings/javascript/qpid-proton/LICENSE b/proton-c/bindings/javascript/qpid-proton/LICENSE
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/proton-c/bindings/javascript/qpid-proton/LICENSE
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/proton-c/bindings/javascript/qpid-proton/README.md b/proton-c/bindings/javascript/qpid-proton/README.md
new file mode 100644
index 0000000..db026c7
--- /dev/null
+++ b/proton-c/bindings/javascript/qpid-proton/README.md
@@ -0,0 +1,4 @@
+qpid-proton
+-----------
+
+apache qpid proton messenger AMQP 1.0 library
diff --git a/proton-c/bindings/javascript/qpid-proton/lib/.gitignore b/proton-c/bindings/javascript/qpid-proton/lib/.gitignore
new file mode 100644
index 0000000..2b1f291
--- /dev/null
+++ b/proton-c/bindings/javascript/qpid-proton/lib/.gitignore
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Currently empty .gitignore
+# Used to ensure git creates the otherwise empty directory
diff --git a/proton-c/bindings/javascript/qpid-proton/package.json b/proton-c/bindings/javascript/qpid-proton/package.json
new file mode 100644
index 0000000..ffc5ebe
--- /dev/null
+++ b/proton-c/bindings/javascript/qpid-proton/package.json
@@ -0,0 +1,11 @@
+{
+    "name" : "qpid-proton",
+    "version": "0.7.0",
+    "description": "apache qpid proton messenger AMQP 1.0 library",
+    "repository": {
+        "type": "svn",
+        "url": "https://svn.apache.org/repos/asf/qpid/proton/trunk/"
+    },
+    "main" : "./lib/proton.js",
+    "dependencies": {}
+}
diff --git a/proton-c/bindings/javascript/subscription.js b/proton-c/bindings/javascript/subscription.js
new file mode 100644
index 0000000..89fd1a3
--- /dev/null
+++ b/proton-c/bindings/javascript/subscription.js
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*****************************************************************************/
+/*                                                                           */
+/*                               Subscription                                */
+/*                                                                           */
+/*****************************************************************************/
+
+/**
+ * Constructs a Subscription instance.
+ * @classdesc This class is a wrapper for Messenger's subscriptions.
+ * Subscriptions should never be *directly* instantiated by client code only via
+ * Messenger.subscribe() or Messenger.incomingSubscription(), so we declare the
+ * constructor in the scope of the package and don't export it via Module.
+ * @constructor Subscription
+ * @param {number} subscription a pointer to the underlying subscription object.
+ * @param {string} source the address that we want to subscribe to.
+ * @param {number} fd the file descriptor associated with the subscription. This
+ *                 is used internally to tidy up during error handling.
+ */
+var Subscription = function(subscription, source, fd) { // Subscription Constructor.
+    this._subscription = subscription;
+    this.source = source;
+    this.fd = fd;
+    if (source.indexOf('~') !== -1) {
+        this.passive = true;
+    } else {
+        this.passive = false;
+    }
+};
+
+/**
+ * TODO Not sure exactly what pn_subscription_get_context does.
+ * @method getContext
+ * @memberof! Subscription#
+ * @returns the Subscription's Context.
+ */
+Subscription.prototype['getContext'] = function() {
+    return _pn_subscription_get_context(this._subscription);
+};
+
+/**
+ * TODO Not sure exactly what pn_subscription_set_context does.
+ * @method setContext
+ * @memberof! Subscription#
+ * @param context the Subscription's new Context.
+ */
+Subscription.prototype['setContext'] = function(context) {
+    _pn_subscription_set_context(this._subscription, context);
+};
+
+/**
+ * @method getAddress
+ * @memberof! Subscription#
+ * @returns the Subscription's Address.
+ */
+Subscription.prototype['getAddress'] = function() {
+    if (this.passive) {
+        return this.source;
+    }
+    return Pointer_stringify(_pn_subscription_address(this._subscription));
+};
+
diff --git a/tests/javascript/codec.js b/tests/javascript/codec.js
new file mode 100644
index 0000000..ce4890d
--- /dev/null
+++ b/tests/javascript/codec.js
@@ -0,0 +1,569 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * This is a fairly literal JavaScript port of codec.py used to unit test the
+ * proton.Data wrapper class. This suite of tests is actually testing the low
+ * level implementation methods used to access the AMQP type system and in
+ * practice most normal users wouldn't need to call these directly, rather users
+ * should simply use the putObject() and getObject() methods.
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var unittest = require("./unittest.js");
+    var assert = require("assert");
+
+    // Increase the virtual heap available to the emscripten compiled C runtime.
+    // This allows us to test a really big string.
+    PROTON_TOTAL_MEMORY = 140000000;
+    PROTON_TOTAL_STACK = 25000000; // Needs to be bigger than the biggest string.
+    var proton = require("qpid-proton");
+
+    // Extend TestCase by creating a prototype instance and adding test methods as properties.
+    var DataTest = new unittest.TestCase();
+
+    DataTest.setUp = function() {
+        this.data = new proton.Data();
+    };
+
+    DataTest.tearDown = function() {
+        this.data.free();
+        this.data = null;
+    };
+    
+    DataTest.testTopLevelNext = function() {
+        console.log("testTopLevelNext");
+        assert(this.data.next() === null);
+        this.data.putNULL();
+        this.data.putBOOL(false);
+        this.data.putINT(0);
+        assert(this.data.next() === null);
+        this.data.rewind();
+        assert(this.data.next() === proton.Data.NULL);
+        assert(this.data.next() === proton.Data.BOOL);
+        assert(this.data.next() === proton.Data.INT);
+        assert(this.data.next() === null);
+        console.log("OK\n");
+    };
+    
+    DataTest.testNestedNext = function() {
+        console.log("testNestedNext");
+        assert(this.data.next() === null);
+        this.data.putNULL();
+        assert(this.data.next() === null);
+        this.data.putLISTNODE();
+        assert(this.data.next() === null);
+        this.data.putBOOL(false);
+        assert(this.data.next() === null);
+        this.data.rewind();
+        assert(this.data.next() === proton.Data.NULL);
+        assert(this.data.next() === proton.Data.LIST);
+        this.data.enter();
+        assert(this.data.next() === null);
+        this.data.putUBYTE(0);
+        assert(this.data.next() === null);
+        this.data.putUINT(0);
+        assert(this.data.next() === null);
+        this.data.putINT(0);
+        assert(this.data.next() === null);
+        this.data.exit();
+        assert(this.data.next() === proton.Data.BOOL);
+        assert(this.data.next() === null);
+    
+        this.data.rewind();
+        assert(this.data.next() === proton.Data.NULL);
+        assert(this.data.next() === proton.Data.LIST);
+        assert(this.data.enter());
+        assert(this.data.next() === proton.Data.UBYTE);
+        assert(this.data.next() === proton.Data.UINT);
+        assert(this.data.next() === proton.Data.INT);
+        assert(this.data.next() === null);
+        assert(this.data.exit());
+        assert(this.data.next() === proton.Data.BOOL);
+        assert(this.data.next() === null);
+        console.log("OK\n");
+    };
+    
+    DataTest.testEnterExit = function() {
+        console.log("testEnterExit");
+        assert(this.data.next() === null);
+        assert(!this.data.enter());
+        this.data.putLISTNODE();
+        assert(this.data.enter());
+        assert(this.data.next() === null);
+        this.data.putLISTNODE();
+        assert(this.data.enter());
+        this.data.putLISTNODE();
+        assert(this.data.enter());
+        assert(this.data.exit());
+        assert(this.data.getLISTNODE() === 0);
+        assert(this.data.exit());
+        assert(this.data.getLISTNODE() === 1);
+        assert(this.data.exit());
+        assert(this.data.getLISTNODE() === 1);
+        assert(!this.data.exit());
+        assert(this.data.getLISTNODE() === 1);
+        assert(this.data.next() === null);
+    
+        this.data.rewind();
+        assert(this.data.next() === proton.Data.LIST);
+        assert(this.data.getLISTNODE() === 1);
+        assert(this.data.enter());
+        assert(this.data.next() === proton.Data.LIST);
+        assert(this.data.getLISTNODE() === 1);
+        assert(this.data.enter());
+        assert(this.data.next() === proton.Data.LIST);
+        assert(this.data.getLISTNODE() === 0);
+        assert(this.data.enter());
+        assert(this.data.next() === null);
+        assert(this.data.exit());
+        assert(this.data.getLISTNODE() === 0);
+        assert(this.data.exit());
+        assert(this.data.getLISTNODE() === 1);
+        assert(this.data.exit());
+        assert(this.data.getLISTNODE() === 1);
+        assert(!this.data.exit());
+        console.log("OK\n");
+    };
+    
+    /**
+     * This tests the "low level" putARRAYNODE/getARRAYNODE methods.
+     * In general though applications would create a proton.Data.Array and use the
+     * higher level putARRAY/getARRAY
+     */
+    DataTest._testArray = function(dtype, descriptor, atype, values) {
+        var values = Array.prototype.slice.apply(arguments, [3]);
+        dtype = (dtype == null) ? null : dtype.toUpperCase();
+        atype = atype.toUpperCase();
+    
+        // Create an array node, enter it and put the descriptor (if present) and values.
+        this.data.putARRAYNODE(dtype != null, proton.Data[atype]);
+        this.data.enter();
+        if (dtype != null) {
+            var putter = 'put' + dtype;
+            this.data[putter](descriptor);
+        }
+        var putter = 'put' + atype;
+        for (var i = 0; i < values.length; i++) {
+            this.data[putter](values[i]);
+        }
+        this.data.exit();
+    
+        // Check that we did indeed add an Array node
+        this.data.rewind();
+        assert(this.data.next() === proton.Data.ARRAY);
+    
+        // Get the count, described and type metadata from the array node and compare
+        // with the values we passed to putARRAYNODE.
+        var metadata = this.data.getARRAYNODE();
+        var count = metadata.count;
+        var described = metadata.described;
+        var type = metadata.type;
+    
+        assert(count === values.length);
+        if (dtype == null) {
+            assert(described === false);
+        } else {
+            assert(described === true);
+        }
+        assert(type === proton.Data[atype]);
+    
+        // Enter the array node and compare the descriptor and values with those that
+        // we put into the array.
+        assert(this.data.enter());
+        if (described) {
+            assert(this.data.next() === proton.Data[dtype]);
+            var getter = 'get' + dtype;
+            var gotten = this.data[getter]();
+            assert(gotten.toString() === descriptor.toString());
+        }
+        var getter = 'get' + atype;
+        for (var i = 0; i < values.length; i++) {
+            assert(this.data.next() === proton.Data[atype]);
+            var gotten = this.data[getter]();
+            assert(gotten.toString() === values[i].toString());
+        }
+        assert(this.data.next() === null);
+        assert(this.data.exit());
+    };
+    
+    DataTest.testStringArray = function() {
+        console.log("testStringArray");
+        this._testArray(null, null, "string", "one", "two", "three");
+    
+        // Now try using the proton.Data.Array class.
+        this.data.clear();
+        var put = new proton.Data.Array("STRING", ["four", "five", "six"]);
+        this.data.putARRAY(put);
+        var get = this.data.getARRAY();
+        assert(get.equals(put));
+        console.log("OK\n");
+    };
+    
+    DataTest.testDescribedStringArray = function() {
+        console.log("testDescribedStringArray");
+        this._testArray("symbol", "url", "string", "one", "two", "three");
+    
+        // Now try using the proton.Data.Array class.
+        this.data.clear();
+        var put = new proton.Data.Array("STRING", ["four", "five", "six"], new proton.Data.Symbol("url"));
+        this.data.putARRAY(put);
+        var get = this.data.getARRAY();
+        assert(get.equals(put));
+        console.log("OK\n");
+    };
+    
+    DataTest.testIntArray = function() {
+        console.log("testIntArray");
+        this._testArray(null, null, "int", 1, 2, 3);
+    
+        // Now try using the proton.Data.Array class.
+        this.data.clear();
+        var put = new proton.Data.Array("INT", [4, 5, 6]);
+        this.data.putARRAY(put);
+        var get = this.data.getARRAY();
+        assert(get.equals(put));
+        console.log("OK\n");
+    };
+    
+    DataTest.testUUIDArray = function() {
+        console.log("testUUIDArray");
+        this._testArray(null, null, "uuid", new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid());
+    
+        // Now try using the proton.Data.Array class.
+        this.data.clear();
+        var put = new proton.Data.Array("UUID", [new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid()]);
+        this.data.putARRAY(put);
+        var get = this.data.getARRAY();
+        assert(get.equals(put));
+        console.log("OK\n");
+    };
+
+    DataTest.testEmptyArray = function() {
+        console.log("testEmptyArray");
+        this._testArray(null, null, "null");
+
+        // Now try using the proton.Data.Array class.
+        this.data.clear();
+        var put = new proton.Data.Array();
+        this.data.putARRAY(put);
+        var get = this.data.getARRAY();
+        assert(get.equals(put));
+        console.log("OK\n");
+    };
+
+    DataTest.testDescribedEmptyArray = function() {
+        console.log("testDescribedEmptyArray");
+        this._testArray("long", 0, "null");
+    
+        // Now try using the proton.Data.Array class.
+        this.data.clear();
+        var put = new proton.Data.Array((0).long());
+        this.data.putARRAY(put);
+        var get = this.data.getARRAY();
+        assert(get.equals(put));
+        console.log("OK\n");
+    };  
+
+    DataTest._test = function(dtype, values) {
+        var values = Array.prototype.slice.apply(arguments, [1]);
+        var lastValue = values[values.length - 1];
+
+        // Default equality function. Note that we use valueOf because some of the
+        // types we are trying to compare (Symbol, Timestamp, Uuid etc.) are object
+        // types and we want to compare their value not whether they are the same object.
+        var eq = function(x, y) {return x.valueOf() === y.valueOf();};
+    
+        if (typeof lastValue === 'function') {
+            eq = values.pop();
+        }
+    
+        dtype = dtype.toUpperCase();
+        var ntype = proton.Data[dtype];
+        var putter = 'put' + dtype;
+        var getter = 'get' + dtype;
+    
+        for (var i = 0; i < values.length; i++) {
+            var v = values[i];
+            /*
+             * Replace the array element with its value. We do this to make testing
+             * simpler for Binary elements. In the case of Binary putBINARY "consumes"
+             * the data, in other words ownership of the underlying raw data transfers
+             * to the Data object so the v object becomes "empty" after calling the
+             * putter. Calling its valueOf() happens to call its toString() which
+             * provides a stringified version of the Binary whilst also working for
+             * the other data types we want to test too.
+             */
+            values[i] = v.valueOf();
+            this.data[putter](v);
+            var gotten = this.data[getter]();
+            assert(eq(gotten, values[i]));
+        }
+    
+        this.data.rewind();
+    
+        for (var i = 0; i < values.length; i++) {
+            var v = values[i];
+            var vtype = this.data.next();
+            assert(vtype === ntype);
+            var gotten = this.data[getter]();
+            assert(eq(gotten, v));
+        }
+    
+        // Test encode and decode methods.
+        var encoded = this.data.encode();
+        var copy = new proton.Data();
+        while (encoded) {
+            encoded = copy.decode(encoded);
+        }
+        copy.rewind();
+    
+        for (var i = 0; i < values.length; i++) {
+            var v = values[i];
+            var vtype = copy.next();
+            assert(vtype === ntype);
+            var gotten = copy[getter]();
+            assert(eq(gotten, v));
+        }
+        copy.free();
+    };  
+    
+    DataTest.testInt = function() {
+        console.log("testInt");
+        this._test("int", 1, 2, 3, -1, -2, -3);
+        console.log("OK\n");
+    
+    };  
+
+    DataTest.testString = function() {
+        console.log("testString");
+        this._test("string", "one", "two", "three", "this is a test", "");
+        console.log("OK\n");
+    };  
+
+    DataTest.testBigString = function() {
+        // Try a 2MB string, this is about as big as we can cope with using the default
+        // emscripten heap size.
+        console.log("testBigString");
+        var data = "";
+        for (var i = 0; i < 2000000; i++) {
+            data += "*";
+        }
+        var string = "start\n" + data + "\nfinish\n";
+        this._test("string", string);
+        console.log("OK\n");
+    };  
+
+/* TODO - currently emscripten isn't respecting Module['TOTAL_STACK'] so setting PROTON_TOTAL_STACK doesn't actually increase the stack size.
+    DataTest.testReallyBigString = function() {
+        // Try a 20MB string, this needs a bigger emscripten heap size and more stack
+        // as the default stack is 5MB and strings are allocated on the stack.
+        console.log("testReallyBigString");
+        var data = "";
+        for (var i = 0; i < 20000000; i++) {
+            data += "*";
+        }
+        var string = "start\n" + data + "\nfinish\n";
+        this._test("string", string);
+        console.log("OK\n");
+    };
+*/
+
+    DataTest.testFloat = function() {
+        console.log("testFloat");
+        // We have to use a special comparison here because JavaScript internally
+        // only uses doubles and converting between floats and doubles is imprecise.
+        this._test("float", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3,
+                   function(x, y) {return (x - y < 0.000001);});
+        console.log("OK\n");
+    };  
+
+    DataTest.testDouble = function() {
+        console.log("testDouble");
+        this._test("double", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3);
+        console.log("OK\n");
+    };  
+
+    DataTest.testBinary = function() {
+        console.log("testBinary");
+        this._test("binary", new proton.Data.Binary(["t".char(), "h".char(), "i".char(), "s".char()]),
+                   new proton.Data.Binary("is"), new proton.Data.Binary("a"), new proton.Data.Binary("test"),
+                   new proton.Data.Binary("of"), new proton.Data.Binary("двоичные данные"));
+        console.log("OK\n");
+    };  
+
+    DataTest.testSymbol = function() {
+        console.log("testSymbol");
+        this._test("symbol", new proton.Data.Symbol("this is a symbol test"),
+                             new proton.Data.Symbol("bleh"), new proton.Data.Symbol("blah"));
+        console.log("OK\n");
+    };
+
+    DataTest.testTimestamp = function() {
+        console.log("testTimestamp");
+        this._test("timestamp", new Date(0), new Date(12345), new Date(1000000));
+        console.log("OK\n");
+    };  
+
+    DataTest.testChar = function() {
+        console.log("testChar");
+        this._test("char", 'a', 'b', 'c', '\u1234');
+        console.log("OK\n");
+    };  
+
+    DataTest.testUUID = function() {
+        console.log("testUUID");
+        this._test("uuid", new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid());
+        console.log("OK\n");
+    };
+
+    /* TODO
+    DataTest.testDecimal32 = function() {
+        console.log("testDecimal32");
+        //this._test("decimal32", 0, 1, 2, 3, 4, Math.pow(2, 30));
+    };
+
+    DataTest.testDecimal64 = function() {
+        console.log("testDecimal64");
+        //this._test("decimal64", 0, 1, 2, 3, 4, Math.pow(2, 60));
+    };  
+
+    DataTest.testDecimal128 = function() {
+        console.log("testDecimal128");
+        // TODO
+    };
+    */
+
+    DataTest.testCopy = function() {
+        console.log("testCopy");
+        this.data.putDESCRIBEDNODE();
+        this.data.enter();
+        this.data.putULONG(123);
+        this.data.putMAPNODE();
+        this.data.enter();
+        this.data.putSTRING("pi");
+        this.data.putDOUBLE(3.14159265359);
+        this.data.exit();
+        this.data.exit();
+    
+        var dst = this.data.copy();
+        var copy = dst.format();
+        var orig = this.data.format();
+        assert(copy === orig);
+        dst.free();
+        console.log("OK\n");
+    };  
+
+    DataTest.testCopyNested = function() {
+        console.log("testCopyNested");
+        var nested = [1, 2, 3, [4, 5, 6], 7, 8, 9];
+        this.data.putObject(nested);
+        var dst = this.data.copy();
+        assert(dst.format() === this.data.format());
+        dst.free();
+        console.log("OK\n");
+    };  
+
+    DataTest.testCopyNestedArray = function() {
+        console.log("testCopyNestedArray");
+        var nested = [new proton.Data.Array("LIST", [
+                        ["first",  [new proton.Data.Array("INT", [1, 2, 3]), "this"]],
+                        ["second", [new proton.Data.Array("INT", [1, 2, 3]), "is"]],
+                        ["third",  [new proton.Data.Array("INT", [1, 2, 3]), "fun"]]
+                        ]),
+                    "end"];
+        this.data.putObject(nested);
+        var dst = this.data.copy();
+        assert(dst.format() === this.data.format());
+        dst.free();
+        console.log("OK\n");
+    };
+
+    DataTest.testRoundTrip = function() {
+        console.log("testRoundTrip");
+        var obj = {key: new Date(1234),
+                   123: "blah",
+                   c: "bleh",
+                   desc: new proton.Data.Described("http://example.org", new proton.Data.Symbol("url")),
+                   array: new proton.Data.Array("INT", [1, 2, 3]),
+                   list: [1, 2, 3, null, 4],
+                   boolean: true};
+        // Serialise obj into this.data.
+        this.data.putObject(obj);
+    
+        // Encode this.data into a Binary representation.
+        var enc = this.data.encode();
+    
+        // Create a new Data instance and decode from the Binary representation
+        // consuming the Binary contents in the process.
+        var data = new proton.Data();
+        data.decode(enc);
+    
+        assert(data.format() === this.data.format());
+    
+        // Deserialise from the copied Data instance into a new JavaScript Object.
+        data.rewind();
+        assert(data.next());
+        var copy = data.getObject();
+    
+        // Create yet another Data instance and serialise the new Object into that.
+        var data1 = new proton.Data();
+        data1.putObject(copy);
+    
+        // Compare the round tripped Data with the original one.
+        assert(data1.format() === this.data.format());
+    
+        data.free();
+        data1.free();
+        console.log("OK\n");
+    };
+
+    DataTest.testLookup = function() {
+        console.log("testLookup");
+        var obj = {key: "value",
+                   pi: 3.14159,
+                   list: [1, 2, 3, 4]};
+        // Serialise obj into this.data.
+        this.data.putObject(obj);
+        this.data.rewind();
+        this.data.next();
+        this.data.enter();
+        this.data.narrow();
+        assert(this.data.lookup("pi"));
+        assert(this.data.getObject() === 3.14159);
+        this.data.rewind();
+        assert(this.data.lookup("key"));
+        assert(this.data.getObject() === "value");
+        this.data.rewind();
+        assert(this.data.lookup("list"));
+        assert(this.data.getObject().toString() === "1,2,3,4");
+        this.data.widen();
+        this.data.rewind();
+        assert(!this.data.lookup("pi"));
+        console.log("OK\n");
+    };  
+
+    DataTest.run();
+} else {
+    console.error("codec.js should be run in Node.js");
+}
+
diff --git a/tests/javascript/message.js b/tests/javascript/message.js
new file mode 100644
index 0000000..dca6f68
--- /dev/null
+++ b/tests/javascript/message.js
@@ -0,0 +1,359 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * This is a fairly literal JavaScript port of message.py used to unit test the
+ * proton.Message wrapper class.
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var unittest = require("./unittest.js");
+    var assert = require("assert");
+    var proton = require("qpid-proton");
+
+    /**
+     * JavaScript Implementation of Python's range() function taken from:
+     * http://stackoverflow.com/questions/8273047/javascript-function-similar-to-python-range
+     */
+    var range = function(start, stop, step) {
+        if (typeof stop == 'undefined') {
+            // one param defined
+            stop = start;
+            start = 0;
+        };
+        if (typeof step == 'undefined') {
+            step = 1;
+        };
+        if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
+            return [];
+        };
+        var result = [];
+        for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
+            result.push(i);
+        };
+        return result;
+    };
+
+
+    // Extend TestCase by creating a new Test class as we're using it in a few places.
+    var Test = function() { // Test constructor.
+        /**
+         * The following call is the equivalent of "super" in Java. It's not necessary
+         * here as the unittest.TestCase constructor doesn't set any state, but it
+         * is the correct thing to do when implementing classical inheritance in
+         * JavaScript so I've kept it here as a useful reminder of the "pattern".
+         */
+        //unittest.TestCase.prototype.constructor.call(this);
+    };  
+
+    Test.prototype = new unittest.TestCase(); // Here's where the inheritance occurs.
+    Test.prototype.constructor = Test; // Otherwise instances of Test would have a constructor of unittest.TestCase.
+
+    Test.prototype.setUp = function() {
+        this.msg = new proton.Message();
+    };
+
+    Test.prototype.tearDown = function() {
+        this.msg.free();
+        this.msg = null;
+    };
+
+
+    // Extend Test more simply by creating a prototype instance and adding test methods as properties.
+
+    var AccessorsTest = new Test();
+
+    AccessorsTest._test = function(name, defaultValue, values) {
+        /**
+         * For the case of Binary values under test we retrieve their toString().
+         * This is because the methods under test "consume" the data, in other
+         * words ownership of the underlying raw data transfers to the Message
+         * object so the sent Binary object becomes "empty" after calling the setter.
+         * In addition Binary values merely contain a "pointer" to the raw data
+         * so even a "deepEqual" comparison won't accurately compare two Binaries.
+         * For these tests we "cheat" and store an array of characters in the
+         * Binary so that we can use their String forms for comparison tests.
+         *
+         * We also get the String value of Uuid for the case of setUserID because
+         * that method transparently creates Binary values from the String form
+         * of non-Binary data passed to it. It's a convenience method, but makes
+         * testing somewhat more fiddly.
+         */
+
+        // First get the values passed to the method.
+        var values = Array.prototype.slice.apply(arguments, [2]);
+        // If the first element of values is actually an Array then use the Array.
+        // This scenario is what happens in the tests that use the range() function.
+        values = (Object.prototype.toString.call(values[0]) === '[object Array]') ? values[0] : values;
+    
+        // Work out the accessor/mutator names noting that boolean accessors use "is" not "get".
+        var setter = 'set' + name;
+        var getter = (typeof defaultValue === 'boolean') ? 'is' + name : 'get' + name;
+    
+        // Get the message's default value first.
+        var d = this.msg[getter]();
+        d = (d instanceof proton.Data.Binary) ? d.toString() : d;
+    
+        // Compare the message's default with the expected default value passed in the test case.
+        assert.deepEqual(d, defaultValue);
+    
+        for (var i = 0; i < values.length; i++) {
+            var v = values[i];
+    
+            var value = (v instanceof proton.Data.Binary ||
+                         (name === 'UserID' && v instanceof proton.Data.Uuid)) ? v.toString() : v;
+            value = (v instanceof Date) ? v.valueOf() : v;
+    
+            this.msg[setter](v); // This call will "consume" Binary data.
+    
+            var gotten = this.msg[getter]();
+            gotten = (gotten instanceof proton.Data.Binary) ? gotten.toString() : gotten;
+            gotten = (gotten instanceof Date) ? gotten.valueOf() : v;
+    
+            assert.deepEqual(value, gotten);
+        }
+    };
+
+    AccessorsTest._testString = function(name) {
+        this._test(name, "", "asdf", "fdsa", "");
+    };  
+
+    AccessorsTest._testTime = function(name) {
+        // The ExpiryTime and CreationTime methods can take either a number or a Date Object.
+        this._test(name, new Date(0), new Date(0), 123456789, new Date(987654321));
+    };
+
+    AccessorsTest.testID = function() {
+        console.log("testID");
+        this._test("ID", null, "bytes", null, 123, "string", new proton.Data.Uuid(), new proton.Data.Binary("ВИНАРЫ"));
+        console.log("OK\n");
+    };  
+
+    AccessorsTest.testCorrelationID = function() {
+        console.log("testCorrelationID");
+        this._test("CorrelationID", null, "bytes", null, 123, "string", new proton.Data.Uuid(), new proton.Data.Binary("ВИНАРЫ"));
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testDurable = function() {
+        console.log("testDurable");
+        this._test("Durable", false, true, false);
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testPriority = function() {
+        console.log("testPriority");
+        this._test("Priority", proton.Message.DEFAULT_PRIORITY, range(0, 256));
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testTTL = function() {
+        console.log("testTTL");
+        this._test("TTL", 0, range(12345, 54321));
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testFirstAcquirer = function() {
+        console.log("testFirstAcquirer");
+        this._test("FirstAcquirer", false, true, false);
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testDeliveryCount = function() {
+        console.log("testDeliveryCount");
+        this._test("DeliveryCount", 0, range(0, 1024));
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testUserID = function() {
+        console.log("testUserID");
+        this._test("UserID", "", "asdf", "fdsa", 123, new proton.Data.Binary("ВИНАРЫ"), new proton.Data.Uuid(), "");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testAddress = function() {
+        console.log("testAddress");
+        this._testString("Address");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testSubject = function() {
+        console.log("testSubject");
+        this._testString("Subject");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testReplyTo = function() {
+        console.log("testReplyTo");
+        this._testString("ReplyTo");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testContentType = function() {
+        console.log("testContentType");
+        this._testString("ContentType");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testContentEncoding = function() {
+        console.log("testContentEncoding");
+        this._testString("ContentEncoding");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testExpiryTime = function() {
+        console.log("testExpiryTime");
+        this._testTime("ExpiryTime");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testCreationTime = function() {
+        console.log("testCreationTime");
+        this._testTime("CreationTime");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testGroupID = function() {
+        console.log("testGroupID");
+        this._testString("GroupID");
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testGroupSequence = function() {
+        console.log("testGroupSequence");
+        this._test("GroupSequence", 0, 0, -10, 10, 20, -20);
+        console.log("OK\n");
+    };
+
+    AccessorsTest.testReplyToGroupID = function() {
+        console.log("testReplyToGroupID");
+        this._testString("ReplyToGroupID");
+        console.log("OK\n");
+    };
+
+
+    var CodecTest = new Test();
+
+    CodecTest.testRoundTrip = function() {
+        console.log("testRoundTrip");
+        this.msg.setID("asdf");
+        this.msg.setCorrelationID(new proton.Data.Uuid());
+        this.msg.setTTL(3);
+        this.msg.setPriority(100);
+        this.msg.setAddress("address");
+        this.msg.setSubject("subject");
+        this.msg.body = "Hello World!";
+    
+        var data = this.msg.encode();
+        var msg2 = new proton.Message();
+        msg2.decode(data);
+    
+        assert(this.msg.getID() === msg2.getID());
+        assert(this.msg.getCorrelationID().toString() === msg2.getCorrelationID().toString());
+        assert(this.msg.getTTL() === msg2.getTTL());
+        assert(this.msg.getPriority() === msg2.getPriority());
+        assert(this.msg.getAddress() === msg2.getAddress());
+        assert(this.msg.getSubject() === msg2.getSubject());
+        assert(this.msg.body === msg2.body);
+
+        msg2.free();
+        console.log("OK\n");
+    };
+
+    /**
+     * This test tests the transparent serialisation and deserialisation of JavaScript
+     * Objects using the AMQP type system (this is the default behaviour).
+     */
+    CodecTest.testRoundTripBodyObject = function() {
+        console.log("testRoundTripBodyObject");
+        this.msg.setAddress("address");
+        this.msg.body = {array: [1, 2, 3, 4], object: {name: "John Smith", age: 65}};
+
+        var data = this.msg.encode();
+        var msg2 = new proton.Message();
+        msg2.decode(data);
+    
+        assert(this.msg.getAddress() === msg2.getAddress());
+        assert(this.msg.getContentType() === msg2.getContentType());
+        assert.deepEqual(this.msg.body, msg2.body);
+
+        msg2.free();
+        console.log("OK\n");
+    };
+
+    /**
+     * This test tests the transparent serialisation and deserialisation of JavaScript
+     * Objects as JSON. In this case the "on-the-wire" representation is an AMQP binary
+     * stored in the AMQP data section.
+     */
+    CodecTest.testRoundTripBodyObjectAsJSON = function() {
+        console.log("testRoundTripBodyObjectAsJSON");
+        this.msg.setAddress("address");
+        this.msg.setContentType("application/json");
+        this.msg.body = {array: [1, 2, 3, 4], object: {name: "John Smith", age: 65}};
+    
+        var data = this.msg.encode();
+        var msg2 = new proton.Message();
+        msg2.decode(data);
+    
+        assert(this.msg.getAddress() === msg2.getAddress());
+        assert(this.msg.getContentType() === msg2.getContentType());
+        assert.deepEqual(this.msg.body, msg2.body);
+    
+        msg2.free();
+        console.log("OK\n");
+    };
+
+    /**
+     * By default the API will encode using the AMQP type system, but is the content-type
+     * is set it will encode as an opaque Binary in an AMQP data section. For certain
+     * types however this isn't the most useful thing. For application/json (see
+     * previous test) we convert to and from JavaScript Objects and for text/* MIME
+     * types the API will automatically convert the received Binary into a String.
+     */
+    CodecTest.testRoundTripMIMETextObject = function() {
+        console.log("testRoundTripMIMETextObject");
+        this.msg.setAddress("address");
+        this.msg.setContentType("text/plain");
+        this.msg.body = "some text";
+    
+        var data = this.msg.encode();
+        var msg2 = new proton.Message();
+        msg2.decode(data);
+
+        assert(this.msg.getAddress() === msg2.getAddress());
+        assert(this.msg.getContentType() === msg2.getContentType());
+        assert.deepEqual(this.msg.body, msg2.body);
+
+        msg2.free();
+        console.log("OK\n");
+    };
+
+
+    // load and save are deprecated so not implemented in the JavaScript binding.
+
+    AccessorsTest.run();
+    CodecTest.run();
+} else {
+    console.error("message.js should be run in Node.js");
+}
+
diff --git a/tests/javascript/soak.js b/tests/javascript/soak.js
new file mode 100755
index 0000000..8ecce6a
--- /dev/null
+++ b/tests/javascript/soak.js
@@ -0,0 +1,93 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if not log an error and exit.
+if (typeof process === 'object' && typeof require === 'function') {
+    var proton = require("qpid-proton");
+
+    var addr = 'guest:guest@localhost:5673';
+    //var addr = 'localhost:5673';
+    var address = 'amqp://' + addr;
+    console.log(address);
+
+    var subscriptionQueue = '';
+    var count = 0;
+    var start = 0; // Start Time.
+
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    var pumpData = function() {
+        while (messenger.incoming()) {
+            // The second parameter forces Binary payloads to be decoded as strings
+            // this is useful because the broker QMF Agent encodes strings as AMQP
+            // binary, which is a right pain from an interoperability perspective.
+            var t = messenger.get(message, true);
+            //console.log("Address: " + message.getAddress());
+            //console.log("Content: " + message.body);
+            messenger.accept(t);
+    
+            if (count % 1000 === 0) {
+                var time = +new Date();
+                console.log("count = " + count + ", duration = " + (time - start) + ", rate = " + ((count*1000)/(time - start)));
+            }
+
+            sendMessage();
+        }
+
+        if (messenger.isStopped()) {
+            message.free();
+            messenger.free();
+        }
+    };
+
+    var sendMessage = function() {
+        var msgtext = "Message Number " + count;
+        count++;
+
+        message.setAddress(address + '/' + subscriptionQueue);
+        message.body = msgtext;
+        messenger.put(message);
+        //messenger.settle();
+    };
+
+    messenger.on('error', function(error) {console.log(error);});
+    messenger.on('work', pumpData);
+    messenger.on('subscription', function(subscription) {
+        var subscriptionAddress = subscription.getAddress();
+        var splitAddress = subscriptionAddress.split('/');
+        subscriptionQueue = splitAddress[splitAddress.length - 1];
+
+        console.log("Subscription Queue: " + subscriptionQueue);
+        start = +new Date();
+        sendMessage();
+    });
+
+    //messenger.setOutgoingWindow(1024);
+    messenger.setIncomingWindow(1024); // The Java Broker seems to need this.
+    messenger.recv(); // Receive as many messages as messenger can buffer.
+    messenger.start();
+
+    messenger.subscribe('amqp://' + addr + '/#');
+} else {
+    console.error("soak.js should be run in Node.js");
+}
+
diff --git a/tests/javascript/unittest.js b/tests/javascript/unittest.js
new file mode 100644
index 0000000..bc1567c
--- /dev/null
+++ b/tests/javascript/unittest.js
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * The TestCase class provides a simple dependency-free Unit Test framework to
+ * automagically invoke methods that start with "test" on classes that extend it.
+ */
+
+// TestCase Constructor
+var TestCase = function() {};
+
+// Enumerate all functions of the class and invoke those beginning with "test".
+TestCase.prototype.run = function() {
+    for (var property in this) {
+        if ((typeof this[property] === 'function') &&
+            property.lastIndexOf('test', 0) === 0) {
+            this.setUp();
+            this[property]();
+            this.tearDown();
+        }
+    }
+};
+
+TestCase.prototype.setUp = function() {};
+TestCase.prototype.tearDown = function() {};
+
+module.exports.TestCase = TestCase;
+
diff --git a/tools/cmake/Modules/FindEmscripten.cmake b/tools/cmake/Modules/FindEmscripten.cmake
new file mode 100644
index 0000000..7289731
--- /dev/null
+++ b/tools/cmake/Modules/FindEmscripten.cmake
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# FindEmscripten
+# This module checks if Emscripten and its prerequisites are installed and if so
+# sets EMSCRIPTEN_FOUND Emscripten (https://github.com/kripken/emscripten) is a
+# C/C++ to JavaScript cross-compiler used to generate the JavaScript bindings.
+
+if (NOT EMSCRIPTEN_FOUND)
+    # First check that Node.js is installed as that is needed by Emscripten.
+    find_program(NODE node)
+    if (NOT NODE)
+        message(STATUS "Node.js (http://nodejs.org) is not installed: can't build JavaScript binding")
+    else (NOT NODE)
+        # Check that the Emscripten C/C++ to JavaScript cross-compiler is installed.
+        find_program(EMCC emcc)
+        if (NOT EMCC)
+            message(STATUS "Emscripten (https://github.com/kripken/emscripten) is not installed: can't build JavaScript binding")
+        else (NOT EMCC)
+            set(EMSCRIPTEN_FOUND ON)
+        endif (NOT EMCC)
+    endif (NOT NODE)
+endif (NOT EMSCRIPTEN_FOUND)
+
diff --git a/tools/cmake/Modules/FindNodePackages.cmake b/tools/cmake/Modules/FindNodePackages.cmake
new file mode 100644
index 0000000..bfbb36f
--- /dev/null
+++ b/tools/cmake/Modules/FindNodePackages.cmake
@@ -0,0 +1,69 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# FindNodePackages
+# This module finds and installs (using npm) node.js packages that are used by
+# the JavaScript binding. The binding should still compile if these packages
+# cannot be installed but certain features might not work as described below.
+#
+# * The ws package is the WebSocket library used by emscripten when the target is
+#   node.js, it isn't needed for applications hosted on a browser (where native 
+#   WebSockets will be used), but without it it won't work with node.js.
+#
+# * The jsdoc package is a JavaScript API document generator analogous to Doxygen
+#   or JavaDoc, it is used by the docs target in the JavaScript binding.
+
+if (NOT NODE_PACKAGES_FOUND)
+    # Check if the specified node.js package is already installed, if not install it.
+    macro(InstallPackage varname name)
+        execute_process(
+            COMMAND npm list --local ${name}
+            OUTPUT_VARIABLE check_package
+        )
+
+        set(${varname} OFF)
+
+        if (check_package MATCHES "${name}@.")
+            message(STATUS "Found node.js package: ${name}")
+            set(${varname} ON)
+        else()
+            message(STATUS "Installing node.js package: ${name}")
+
+            execute_process(
+                COMMAND npm install ${name}
+                WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+                OUTPUT_VARIABLE var
+            )
+
+            if (var)
+                message(STATUS "Installed node.js package: ${name}")
+                set(${varname} ON)
+            endif (var)
+        endif()
+    endmacro()
+
+    # Check if ws WebSocket library https://github.com/einaros/ws is installed
+    InstallPackage("NODE_WS_FOUND" "ws")
+
+    # Check if jsdoc3 API documentation generator https://github.com/jsdoc3/jsdoc is installed
+    InstallPackage("NODE_JSDOC_FOUND" "jsdoc")
+
+    set(NODE_PACKAGES_FOUND ON)
+endif (NOT NODE_PACKAGES_FOUND)
+
