diff --git a/lib/js/src/thrift.js b/lib/js/src/thrift.js
new file mode 100644
index 0000000..3b489e5
--- /dev/null
+++ b/lib/js/src/thrift.js
@@ -0,0 +1,1103 @@
+/*
+ * 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.
+ */
+
+/*jshint evil:true*/
+
+/**
+ * The Thrift namespace houses the Apache Thrift JavaScript library 
+ * elements providing JavaScript bindings for the Apache Thrift RPC 
+ * system. Users will typically only directly make use of the 
+ * Transport and Protocol constructors.
+ * @namespace
+ * @example
+ *     var transport = new Thrift.Transport("http://localhost:8585");
+ *     var protocol  = new Thrift.Protocol(transport);
+ *     var client = new MyThriftSvcClient(protocol);
+ *     var result = client.MyMethod();
+ */
+var Thrift = {
+    /**
+     * Thrift JavaScript library version.
+     * @readonly
+     * @const {string} Version
+     * @memberof Thrift
+     */
+    Version: '1.0.0-dev',
+
+    /**
+     * Thrift IDL type string to Id mapping.
+     * @readonly
+     * @property {number}  STOP   - End of a set of fields.
+     * @property {number}  VOID   - No value (only legal for return types).
+     * @property {number}  BOOL   - True/False integer.
+     * @property {number}  BYTE   - Signed 8 bit integer.
+     * @property {number}  I08    - Signed 8 bit integer.     
+     * @property {number}  DOUBLE - 64 bit IEEE 854 floating point.
+     * @property {number}  I16    - Signed 16 bit integer.
+     * @property {number}  I32    - Signed 32 bit integer.
+     * @property {number}  I64    - Signed 64 bit integer.
+     * @property {number}  STRING - Array of bytes representing a string of characters.
+     * @property {number}  UTF7   - Array of bytes representing a string of UTF7 encoded characters.
+     * @property {number}  STRUCT - A multifield type.
+     * @property {number}  MAP    - A collection type (map/associative-array/dictionary).
+     * @property {number}  SET    - A collection type (unordered and without repeated values).
+     * @property {number}  LIST   - A collection type (unordered).
+     * @property {number}  UTF8   - Array of bytes representing a string of UTF8 encoded characters.
+     * @property {number}  UTF16  - Array of bytes representing a string of UTF16 encoded characters.
+     */
+    Type: {
+        'STOP' : 0,
+        'VOID' : 1,
+        'BOOL' : 2,
+        'BYTE' : 3,
+        'I08' : 3,
+        'DOUBLE' : 4,
+        'I16' : 6,
+        'I32' : 8,
+        'I64' : 10,
+        'STRING' : 11,
+        'UTF7' : 11,
+        'STRUCT' : 12,
+        'MAP' : 13,
+        'SET' : 14,
+        'LIST' : 15,
+        'UTF8' : 16,
+        'UTF16' : 17
+    },
+
+    /**
+     * Thrift RPC message type string to Id mapping.
+     * @readonly
+     * @property {number}  CALL      - RPC call sent from client to server.
+     * @property {number}  REPLY     - RPC call normal response from server to client.
+     * @property {number}  EXCEPTION - RPC call exception response from server to client.
+     * @property {number}  ONEWAY    - Oneway RPC call from client to server with no response.
+     */
+    MessageType: {
+        'CALL' : 1,
+        'REPLY' : 2,
+        'EXCEPTION' : 3,
+        'ONEWAY' : 4
+    },
+
+    /**
+     * Utility function returning the count of an object's own properties.
+     * @param {object} obj - Object to test.
+     * @returns {number} number of object's own properties
+     */
+    objectLength: function(obj) {
+        var length = 0;
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                length++;
+            }
+        }
+
+        return length;
+    },
+
+    /**
+     * Utility function to establish prototype inheritance.
+     * @see {@link http://javascript.crockford.com/prototypal.html|Prototypal Inheritance}
+     * @param {function} constructor - Contstructor function to set as derived.
+     * @param {function} superConstructor - Contstructor function to set as base.
+     * @param {string} [name] - Type name to set as name property in derived prototype.
+     */
+    inherits: function(constructor, superConstructor, name) {
+      function F() {}
+      F.prototype = superConstructor.prototype;
+      constructor.prototype = new F();
+      constructor.prototype.name = name || "";
+    }
+};
+
+/**
+ * Initializes a Thrift TException instance.
+ * @constructor
+ * @augments Error
+ * @param {string} message - The TException message (distinct from the Error message).
+ * @classdesc TException is the base class for all Thrift exceptions types.
+ */
+Thrift.TException = function(message) {
+    this.message = message;
+};
+Thrift.inherits(Thrift.TException, Error, 'TException');
+
+/**
+ * Returns the message set on the exception.
+ * @readonly
+ * @returns {string} exception message
+ */
+Thrift.TException.prototype.getMessage = function() {
+    return this.message;
+};
+
+/**
+ * Thrift Application Exception type string to Id mapping.
+ * @readonly
+ * @property {number}  UNKNOWN                 - Unknown/undefined.
+ * @property {number}  UNKNOWN_METHOD          - Client attempted to call a method unknown to the server.
+ * @property {number}  INVALID_MESSAGE_TYPE    - Client passed an unknown/unsupported MessageType.
+ * @property {number}  WRONG_METHOD_NAME       - Unused.
+ * @property {number}  BAD_SEQUENCE_ID         - Unused in Thrift RPC, used to flag proprietary sequence number errors.
+ * @property {number}  MISSING_RESULT          - Raised by a server processor if a handler fails to supply the required return result.
+ * @property {number}  INTERNAL_ERROR          - Something bad happened.
+ * @property {number}  PROTOCOL_ERROR          - The protocol layer failed to serialize or deserialize data.
+ * @property {number}  INVALID_TRANSFORM       - Unused.
+ * @property {number}  INVALID_PROTOCOL        - The protocol (or version) is not supported.
+ * @property {number}  UNSUPPORTED_CLIENT_TYPE - Unused.
+ */
+Thrift.TApplicationExceptionType = {
+    'UNKNOWN' : 0,
+    'UNKNOWN_METHOD' : 1,
+    'INVALID_MESSAGE_TYPE' : 2,
+    'WRONG_METHOD_NAME' : 3,
+    'BAD_SEQUENCE_ID' : 4,
+    'MISSING_RESULT' : 5,
+    'INTERNAL_ERROR' : 6,
+    'PROTOCOL_ERROR' : 7,
+    'INVALID_TRANSFORM' : 8,
+    'INVALID_PROTOCOL' : 9,
+    'UNSUPPORTED_CLIENT_TYPE' : 10
+};
+
+/**
+ * Initializes a Thrift TApplicationException instance.
+ * @constructor
+ * @augments Thrift.TException
+ * @param {string} message - The TApplicationException message (distinct from the Error message).
+ * @param {Thrift.TApplicationExceptionType} [code] - The TApplicationExceptionType code.
+ * @classdesc TApplicationException is the exception class used to propagate exceptions from an RPC server back to a calling client.
+*/
+Thrift.TApplicationException = function(message, code) {
+    this.message = message;
+    this.code = typeof code === "number" ? code : 0;
+};
+Thrift.inherits(Thrift.TApplicationException, Thrift.TException, 'TApplicationException');
+
+/**
+ * Read a TApplicationException from the supplied protocol.
+ * @param {object} input - The input protocol to read from.
+ */
+Thrift.TApplicationException.prototype.read = function(input) {
+    while (1) {
+        var ret = input.readFieldBegin();
+
+        if (ret.ftype == Thrift.Type.STOP) {
+            break;
+        }
+
+        var fid = ret.fid;
+
+        switch (fid) {
+            case 1:
+                if (ret.ftype == Thrift.Type.STRING) {
+                    ret = input.readString();
+                    this.message = ret.value;
+                } else {
+                    ret = input.skip(ret.ftype);
+                }
+                break;
+            case 2:
+                if (ret.ftype == Thrift.Type.I32) {
+                    ret = input.readI32();
+                    this.code = ret.value;
+                } else {
+                    ret = input.skip(ret.ftype);
+                }
+                break;
+           default:
+                ret = input.skip(ret.ftype);
+                break;
+        }
+
+        input.readFieldEnd();
+    }
+
+    input.readStructEnd();
+};
+
+/**
+ * Wite a TApplicationException to the supplied protocol.
+ * @param {object} output - The output protocol to write to.
+ */
+Thrift.TApplicationException.prototype.write = function(output) {
+    output.writeStructBegin('TApplicationException');
+
+    if (this.message) {
+        output.writeFieldBegin('message', Thrift.Type.STRING, 1);
+        output.writeString(this.getMessage());
+        output.writeFieldEnd();
+    }
+
+    if (this.code) {
+        output.writeFieldBegin('type', Thrift.Type.I32, 2);
+        output.writeI32(this.code);
+        output.writeFieldEnd();
+    }
+
+    output.writeFieldStop();
+    output.writeStructEnd();
+};
+
+/**
+ * Returns the application exception code set on the exception.
+ * @readonly
+ * @returns {Thrift.TApplicationExceptionType} exception code
+ */
+Thrift.TApplicationException.prototype.getCode = function() {
+    return this.code;
+};
+
+/**
+ * Initializes a Thrift Http[s] transport instance.
+ * Note: If you do not specify a url then you must handle XHR on your own
+ *       (this is how to use js bindings in a async fashion).
+ * @constructor
+ * @param {string} [url] - The URL to connect to.
+ * @classdesc The Apache Thrift Transport layer performs byte level I/O between RPC
+ * clients and servers. The JavaScript Transport object type uses Http[s]/XHR and is
+ * the sole browser based Thrift transport. Target servers must implement the http[s] 
+ * transport (see: node.js example server).
+ * @example
+ *     var transport = new Thrift.Transport("http://localhost:8585");
+ */
+Thrift.Transport = function(url) {
+    this.url = url;
+    this.wpos = 0;
+    this.rpos = 0;
+
+    this.send_buf = '';
+    this.recv_buf = '';
+};
+
+Thrift.Transport.prototype = {
+    /**
+     * Gets the browser specific XmlHttpRequest Object.
+     * @returns {object} the browser XHR interface object
+     */
+    getXmlHttpRequestObject: function() {
+        try { return new XMLHttpRequest(); } catch (e1) { }
+        try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { }
+        try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { }
+
+        throw "Your browser doesn't support XHR.";
+    },
+
+    /**
+     * Sends the current XRH request if the transport was created with a URL and
+     * the async parameter if false. If the transport was not created with a URL
+     * or the async parameter is True or the URL is an empty string, the current 
+     * send buffer is returned.
+     * @param {object} async - If true the current send buffer is returned.
+     * @returns {undefined|string} Nothing or the current send buffer.
+     * @throws {string} If XHR fails.
+     */
+    flush: function(async) {
+        //async mode
+        if (async || this.url === undefined || this.url === '') {
+            return this.send_buf;
+        }
+
+        var xreq = this.getXmlHttpRequestObject();
+
+        if (xreq.overrideMimeType) {
+            xreq.overrideMimeType('application/json');
+        }
+
+        xreq.open('POST', this.url, false);
+        xreq.send(this.send_buf);
+
+        if (xreq.readyState != 4) {
+            throw 'encountered an unknown ajax ready state: ' + xreq.readyState;
+        }
+
+        if (xreq.status != 200) {
+            throw 'encountered a unknown request status: ' + xreq.status;
+        }
+
+        this.recv_buf = xreq.responseText;
+        this.recv_buf_sz = this.recv_buf.length;
+        this.wpos = this.recv_buf.length;
+        this.rpos = 0;
+    },
+
+    /**
+     * Creates a jQuery XHR object to be used for a Thrift server call.
+     * @param {object} client - The Thrift Service client object generated by the IDL compiler.
+     * @param {object} postData - The message to send to the server.
+     * @param {function} args - The function to call if the request suceeds.
+     * @param {function} recv_method - The Thrift Service Client receive method for the call.
+     * @returns {object} A new jQuery XHR object.
+     * @throws {string} If the jQuery version is prior to 1.5 or if jQuery is not found.
+     */
+    jqRequest: function(client, postData, args, recv_method) {
+        if (typeof jQuery === 'undefined' ||
+            typeof jQuery.Deferred === 'undefined') {
+            throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests';
+        }
+
+        var thriftTransport = this;
+
+        var jqXHR = jQuery.ajax({
+            url: this.url,
+            data: postData,
+            type: 'POST',
+            cache: false,
+            contentType: 'application/json',
+            dataType: 'text thrift',
+            converters: {
+                'text thrift' : function(responseData) {
+                    thriftTransport.setRecvBuffer(responseData);
+                    var value = recv_method.call(client);
+                    return value;
+                }
+            },
+            context: client,
+            success: jQuery.makeArray(args).pop()
+        });
+
+        return jqXHR;
+    },
+
+    /**
+     * Sets the buffer to use when receiving server responses.
+     * @param {string} buf - The buffer to receive server responses.
+     */
+    setRecvBuffer: function(buf) {
+        this.recv_buf = buf;
+        this.recv_buf_sz = this.recv_buf.length;
+        this.wpos = this.recv_buf.length;
+        this.rpos = 0;
+    },
+
+    /**
+     * Returns true if the transport is open, in browser based JavaScript
+     * this function always returns true.
+     * @readonly
+     * @returns {boolean} Always True.
+     */    
+    isOpen: function() {
+        return true;
+    },
+
+    /**
+     * Opens the transport connection, in browser based JavaScript
+     * this function is a nop.
+     */    
+    open: function() {},
+
+    /**
+     * Closes the transport connection, in browser based JavaScript
+     * this function is a nop.
+     */    
+    close: function() {},
+
+    /**
+     * Returns the specified number of characters from the response
+     * buffer.
+     * @param {number} len - The number of characters to return.
+     * @returns {string} Characters sent by the server.
+     */
+    read: function(len) {
+        var avail = this.wpos - this.rpos;
+
+        if (avail === 0) {
+            return '';
+        }
+
+        var give = len;
+
+        if (avail < len) {
+            give = avail;
+        }
+
+        var ret = this.read_buf.substr(this.rpos, give);
+        this.rpos += give;
+
+        //clear buf when complete?
+        return ret;
+    },
+
+    /**
+     * Returns the entire response buffer.
+     * @returns {string} Characters sent by the server.
+     */
+    readAll: function() {
+        return this.recv_buf;
+    },
+
+    /**
+     * Sets the send buffer to buf.
+     * @param {string} buf - The buffer to send.
+     */    
+    write: function(buf) {
+        this.send_buf = buf;
+    },
+
+    /**
+     * Returns the send buffer.
+     * @readonly
+     * @returns {string} The send buffer.
+     */ 
+    getSendBuffer: function() {
+        return this.send_buf;
+    }
+
+};
+
+/**
+ * Initializes a Thrift JSON protocol instance.
+ * @constructor
+ * @param {Thrift.Transport} transport - The transport to serialize to/from.
+ * @classdesc Apache Thrift Protocols perform serialization which enables cross 
+ * language RPC. The Protocol type is the JavaScript browser implementation 
+ * of the Apache Thrift TJSONProtocol.
+ * @example
+ *     var protocol  = new Thrift.Protocol(transport);
+ */
+Thrift.Protocol = function(transport) {
+    this.transport = transport;
+};
+
+/**
+ * Thrift IDL type Id to string mapping.
+ * @readonly
+ * @see {@link Thrift.Type}
+ */
+Thrift.Protocol.Type = {};
+Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"';
+Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"';
+Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"';
+Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"';
+Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"';
+Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"';
+Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"';
+Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"';
+Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"';
+Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"';
+Thrift.Protocol.Type[Thrift.Type.SET] = '"set"';
+
+/**
+ * Thrift IDL type string to Id mapping.
+ * @readonly
+ * @see {@link Thrift.Type}
+ */
+Thrift.Protocol.RType = {};
+Thrift.Protocol.RType.tf = Thrift.Type.BOOL;
+Thrift.Protocol.RType.i8 = Thrift.Type.BYTE;
+Thrift.Protocol.RType.i16 = Thrift.Type.I16;
+Thrift.Protocol.RType.i32 = Thrift.Type.I32;
+Thrift.Protocol.RType.i64 = Thrift.Type.I64;
+Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE;
+Thrift.Protocol.RType.rec = Thrift.Type.STRUCT;
+Thrift.Protocol.RType.str = Thrift.Type.STRING;
+Thrift.Protocol.RType.map = Thrift.Type.MAP;
+Thrift.Protocol.RType.lst = Thrift.Type.LIST;
+Thrift.Protocol.RType.set = Thrift.Type.SET;
+
+/**
+ * The TJSONProtocol version number.
+ * @readonly
+ * @const {number} Version
+ * @memberof Thrift.Protocol
+ */
+ Thrift.Protocol.Version = 1;
+
+Thrift.Protocol.prototype = {
+    /**
+     * Returns the underlying transport.
+     * @readonly
+     * @returns {Thrift.Transport} The underlying transport.
+     */ 
+    getTransport: function() {
+        return this.transport;
+    },
+
+    /**
+     * Serializes the beginning of a Thrift RPC message.
+     * @param {string} name - The service method to call.
+     * @param {Thrift.MessageType} messageType - The type of method call.
+     * @param {number} seqid - The sequence number of this call (always 0 in Apache Thrift).
+     */
+    writeMessageBegin: function(name, messageType, seqid) {
+        this.tstack = [];
+        this.tpos = [];
+
+        this.tstack.push([Thrift.Protocol.Version, '"' +
+            name + '"', messageType, seqid]);
+    },
+
+    /**
+     * Serializes the end of a Thrift RPC message.
+     */
+    writeMessageEnd: function() {
+        var obj = this.tstack.pop();
+
+        this.wobj = this.tstack.pop();
+        this.wobj.push(obj);
+
+        this.wbuf = '[' + this.wobj.join(',') + ']';
+
+        this.transport.write(this.wbuf);
+     },
+
+
+    /**
+     * Serializes the beginning of a struct.
+     * @param {string} name - The name of the struct.
+     */
+    writeStructBegin: function(name) {
+        this.tpos.push(this.tstack.length);
+        this.tstack.push({});
+    },
+
+    /**
+     * Serializes the end of a struct.
+     */
+    writeStructEnd: function() {
+
+        var p = this.tpos.pop();
+        var struct = this.tstack[p];
+        var str = '{';
+        var first = true;
+        for (var key in struct) {
+            if (first) {
+                first = false;
+            } else {
+                str += ',';
+            }
+
+            str += key + ':' + struct[key];
+        }
+
+        str += '}';
+        this.tstack[p] = str;
+    },
+
+    /**
+     * Serializes the beginning of a struct field.
+     * @param {string} name - The name of the field.
+     * @param {Thrift.Protocol.Type} fieldType - The data type of the field.
+     * @param {number} fieldId - The field's unique identifier.
+     */
+    writeFieldBegin: function(name, fieldType, fieldId) {
+        this.tpos.push(this.tstack.length);
+        this.tstack.push({ 'fieldId': '"' +
+            fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType]
+        });
+
+    },
+
+    /**
+     * Serializes the end of a field.
+     */
+    writeFieldEnd: function() {
+        var value = this.tstack.pop();
+        var fieldInfo = this.tstack.pop();
+
+        this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' +
+            fieldInfo.fieldType + ':' + value + '}';
+        this.tpos.pop();
+    },
+
+    /**
+     * Serializes the end of the set of fields for a struct.
+     */
+    writeFieldStop: function() {
+        //na
+    },
+
+    /**
+     * Serializes the beginning of a map collection.
+     * @param {Thrift.Type} keyType - The data type of the key.
+     * @param {Thrift.Type} valType - The data type of the value.
+     * @param {number} [size] - The number of elements in the map (ignored).
+     */
+    writeMapBegin: function(keyType, valType, size) {
+        this.tpos.push(this.tstack.length);
+        this.tstack.push([Thrift.Protocol.Type[keyType],
+            Thrift.Protocol.Type[valType], 0]);
+    },
+
+    /**
+     * Serializes the end of a map.
+     */
+    writeMapEnd: function() {
+        var p = this.tpos.pop();
+
+        if (p == this.tstack.length) {
+            return;
+        }
+
+        if ((this.tstack.length - p - 1) % 2 !== 0) {
+            this.tstack.push('');
+        }
+
+        var size = (this.tstack.length - p - 1) / 2;
+
+        this.tstack[p][this.tstack[p].length - 1] = size;
+
+        var map = '}';
+        var first = true;
+        while (this.tstack.length > p + 1) {
+            var v = this.tstack.pop();
+            var k = this.tstack.pop();
+            if (first) {
+                first = false;
+            } else {
+                map = ',' + map;
+            }
+
+            if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings
+            map = k + ':' + v + map;
+        }
+        map = '{' + map;
+
+        this.tstack[p].push(map);
+        this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
+    },
+
+    /**
+     * Serializes the beginning of a list collection.
+     * @param {Thrift.Type} elemType - The data type of the elements.
+     * @param {number} size - The number of elements in the list.
+     */
+    writeListBegin: function(elemType, size) {
+        this.tpos.push(this.tstack.length);
+        this.tstack.push([Thrift.Protocol.Type[elemType], size]);
+    },
+
+    /**
+     * Serializes the end of a list.
+     */
+    writeListEnd: function() {
+        var p = this.tpos.pop();
+
+        while (this.tstack.length > p + 1) {
+            var tmpVal = this.tstack[p + 1];
+            this.tstack.splice(p + 1, 1);
+            this.tstack[p].push(tmpVal);
+        }
+
+        this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
+    },
+
+    /**
+     * Serializes the beginning of a set collection.
+     * @param {Thrift.Type} elemType - The data type of the elements.
+     * @param {number} size - The number of elements in the list.
+     */
+    writeSetBegin: function(elemType, size) {
+        this.tpos.push(this.tstack.length);
+        this.tstack.push([Thrift.Protocol.Type[elemType], size]);
+    },
+
+    /**
+     * Serializes the end of a set.
+     */
+    writeSetEnd: function() {
+        var p = this.tpos.pop();
+
+        while (this.tstack.length > p + 1) {
+            var tmpVal = this.tstack[p + 1];
+            this.tstack.splice(p + 1, 1);
+            this.tstack[p].push(tmpVal);
+        }
+
+        this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
+    },
+
+    /** Serializes a boolean */
+    writeBool: function(value) {
+        this.tstack.push(value ? 1 : 0);
+    },
+
+    /** Serializes a number */
+    writeByte: function(i8) {
+        this.tstack.push(i8);
+    },
+
+    /** Serializes a number */
+    writeI16: function(i16) {
+        this.tstack.push(i16);
+    },
+
+    /** Serializes a number */
+    writeI32: function(i32) {
+        this.tstack.push(i32);
+    },
+
+    /** Serializes a number */
+    writeI64: function(i64) {
+        this.tstack.push(i64);
+    },
+
+    /** Serializes a number */
+    writeDouble: function(dbl) {
+        this.tstack.push(dbl);
+    },
+
+    /** Serializes a string */
+    writeString: function(str) {
+        // We do not encode uri components for wire transfer:
+        if (str === null) {
+            this.tstack.push(null);
+        } else {
+            // concat may be slower than building a byte buffer
+            var escapedString = '';
+            for (var i = 0; i < str.length; i++) {
+                var ch = str.charAt(i);      // a single double quote: "
+                if (ch === '\"') {
+                    escapedString += '\\\"'; // write out as: \"
+                } else if (ch === '\\') {    // a single backslash: \
+                    escapedString += '\\\\'; // write out as: \\
+                /* Currently escaped forward slashes break TJSONProtocol.
+                 * As it stands, we can simply pass forward slashes into
+                 * our strings across the wire without being escaped.
+                 * I think this is the protocol's bug, not thrift.js
+                 * } else if(ch === '/') {   // a single forward slash: /
+                 *  escapedString += '\\/';  // write out as \/
+                 * }
+                 */
+                } else if (ch === '\b') {    // a single backspace: invisible
+                    escapedString += '\\b';  // write out as: \b"
+                } else if (ch === '\f') {    // a single formfeed: invisible
+                    escapedString += '\\f';  // write out as: \f"
+                } else if (ch === '\n') {    // a single newline: invisible
+                    escapedString += '\\n';  // write out as: \n"
+                } else if (ch === '\r') {    // a single return: invisible
+                    escapedString += '\\r';  // write out as: \r"
+                } else if (ch === '\t') {    // a single tab: invisible
+                    escapedString += '\\t';  // write out as: \t"
+                } else {
+                    escapedString += ch;     // Else it need not be escaped
+                }
+            }
+            this.tstack.push('"' + escapedString + '"');
+        }
+    },
+
+    /** Serializes a string */
+    writeBinary: function(str) {
+        this.writeString(str);
+    },
+
+    /**
+       @class
+       @name AnonReadMessageBeginReturn
+       @property {string} fname - The name of the service method.
+       @property {Thrift.MessageType} mtype - The type of message call.
+       @property {number} rseqid - The sequence number of the message (0 in Thrift RPC).
+     */
+    /** 
+     * Deserializes the beginning of a message. 
+     * @returns {AnonReadMessageBeginReturn}
+     */
+    readMessageBegin: function() {
+        this.rstack = [];
+        this.rpos = [];
+
+        if (typeof jQuery !== 'undefined') {
+            this.robj = jQuery.parseJSON(this.transport.readAll());
+        } else {
+            this.robj = eval(this.transport.readAll());
+        }
+
+        var r = {};
+        var version = this.robj.shift();
+
+        if (version != Thrift.Protocol.Version) {
+            throw 'Wrong thrift protocol version: ' + version;
+        }
+
+        r.fname = this.robj.shift();
+        r.mtype = this.robj.shift();
+        r.rseqid = this.robj.shift();
+
+
+        //get to the main obj
+        this.rstack.push(this.robj.shift());
+
+        return r;
+    },
+
+    /** Deserializes the end of a message. */
+    readMessageEnd: function() {
+    },
+
+    /** 
+     * Deserializes the beginning of a struct. 
+     * @param {string} [name] - The name of the struct (ignored)
+     * @returns {object} - An object with an empty string fname property
+     */    
+    readStructBegin: function(name) {
+        var r = {};
+        r.fname = '';
+
+        //incase this is an array of structs
+        if (this.rstack[this.rstack.length - 1] instanceof Array) {
+            this.rstack.push(this.rstack[this.rstack.length - 1].shift());
+        }
+
+        return r;
+    },
+
+    /** Deserializes the end of a struct. */
+    readStructEnd: function() {
+        if (this.rstack[this.rstack.length - 2] instanceof Array) {
+            this.rstack.pop();
+        }
+    },
+
+    /**
+       @class
+       @name AnonReadFieldBeginReturn
+       @property {string} fname - The name of the field (always '').
+       @property {Thrift.Type} ftype - The data type of the field.
+       @property {number} fid - The unique identifier of the field.
+     */
+    /** 
+     * Deserializes the beginning of a field. 
+     * @returns {AnonReadFieldBeginReturn}
+     */
+    readFieldBegin: function() {
+        var r = {};
+
+        var fid = -1;
+        var ftype = Thrift.Type.STOP;
+
+        //get a fieldId
+        for (var f in (this.rstack[this.rstack.length - 1])) {
+            if (f === null) {
+              continue;
+            }
+
+            fid = parseInt(f, 10);
+            this.rpos.push(this.rstack.length);
+
+            var field = this.rstack[this.rstack.length - 1][fid];
+
+            //remove so we don't see it again
+            delete this.rstack[this.rstack.length - 1][fid];
+
+            this.rstack.push(field);
+
+            break;
+        }
+
+        if (fid != -1) {
+
+            //should only be 1 of these but this is the only
+            //way to match a key
+            for (var i in (this.rstack[this.rstack.length - 1])) {
+                if (Thrift.Protocol.RType[i] === null) {
+                    continue;
+                }
+
+                ftype = Thrift.Protocol.RType[i];
+                this.rstack[this.rstack.length - 1] =
+                    this.rstack[this.rstack.length - 1][i];
+            }
+        }
+
+        r.fname = '';
+        r.ftype = ftype;
+        r.fid = fid;
+
+        return r;
+    },
+
+    /** Deserializes the end of a field. */
+    readFieldEnd: function() {
+        var pos = this.rpos.pop();
+
+        //get back to the right place in the stack
+        while (this.rstack.length > pos) {
+            this.rstack.pop();
+        }
+
+    },
+
+    /**
+       @class
+       @name AnonReadMapBeginReturn
+       @property {Thrift.Type} ktype - The data type of the key.
+       @property {Thrift.Type} vtype - The data type of the value.
+       @property {number} size - The number of elements in the map.
+     */
+    /** 
+     * Deserializes the beginning of a map. 
+     * @returns {AnonReadMapBeginReturn}
+     */
+    readMapBegin: function() {
+        var map = this.rstack.pop();
+
+        var r = {};
+        r.ktype = Thrift.Protocol.RType[map.shift()];
+        r.vtype = Thrift.Protocol.RType[map.shift()];
+        r.size = map.shift();
+
+
+        this.rpos.push(this.rstack.length);
+        this.rstack.push(map.shift());
+
+        return r;
+    },
+
+    /** Deserializes the end of a map. */
+    readMapEnd: function() {
+        this.readFieldEnd();
+    },
+
+    /**
+       @class
+       @name AnonReadColBeginReturn
+       @property {Thrift.Type} etype - The data type of the element.
+       @property {number} size - The number of elements in the collection.
+     */
+    /** 
+     * Deserializes the beginning of a list. 
+     * @returns {AnonReadColBeginReturn}
+     */
+    readListBegin: function() {
+        var list = this.rstack[this.rstack.length - 1];
+
+        var r = {};
+        r.etype = Thrift.Protocol.RType[list.shift()];
+        r.size = list.shift();
+
+        this.rpos.push(this.rstack.length);
+        this.rstack.push(list);
+
+        return r;
+    },
+
+    /** Deserializes the end of a list. */
+    readListEnd: function() {
+        this.readFieldEnd();
+    },
+
+    /** 
+     * Deserializes the beginning of a set. 
+     * @returns {AnonReadColBeginReturn}
+     */
+    readSetBegin: function(elemType, size) {
+        return this.readListBegin(elemType, size);
+    },
+
+    /** Deserializes the end of a set. */
+    readSetEnd: function() {
+        return this.readListEnd();
+    },
+
+    /** Returns an object with a value property set to 
+     *  False unless the next number in the protocol buffer 
+     *  is 1, in which case teh value property is True */
+    readBool: function() {
+        var r = this.readI32();
+
+        if (r !== null && r.value == '1') {
+            r.value = true;
+        } else {
+            r.value = false;
+        }
+
+        return r;
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readByte: function() {
+        return this.readI32();
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readI16: function() {
+        return this.readI32();
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readI32: function(f) {
+        if (f === undefined) {
+            f = this.rstack[this.rstack.length - 1];
+        }
+
+        var r = {};
+
+        if (f instanceof Array) {
+            if (f.length === 0) {
+                r.value = undefined;
+            } else {
+                r.value = f.shift();
+            }
+        } else if (f instanceof Object) {
+           for (var i in f) {
+                if (i === null) {
+                  continue;
+                }
+                this.rstack.push(f[i]);
+                delete f[i];
+
+                r.value = i;
+                break;
+           }
+        } else {
+            r.value = f;
+            this.rstack.pop();
+        }
+
+        return r;
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readI64: function() {
+        return this.readI32();
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readDouble: function() {
+        return this.readI32();
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readString: function() {
+        var r = this.readI32();
+        return r;
+    },
+
+    /** Returns the an object with a value property set to the 
+        next value found in the protocol buffer */
+    readBinary: function() {
+        return this.readString();
+    },
+
+    /** 
+     * Method to arbitrarily skip over data (not implemented).
+     * @throws {string} this method is not implemented and always throws.
+     */
+    skip: function(type) {
+        throw 'skip not supported yet';
+    }
+};
