diff --git a/lib/js/Gruntfile.js b/lib/js/Gruntfile.js
new file mode 100644
index 0000000..dd6406b
--- /dev/null
+++ b/lib/js/Gruntfile.js
@@ -0,0 +1,70 @@
+//To build dist/thrift.js, dist/thrift.min.js and doc/*
+//run grunt at the command line in this directory.
+//Prerequisites:
+// Node Setup -   nodejs.org
+// Grunt Setup -  npm install  //reads the ./package.json and installs project dependencies
+
+module.exports = function(grunt) {
+  'use strict';
+
+  grunt.initConfig({
+    pkg: grunt.file.readJSON('package.json'),
+    concat: {
+      options: {
+        separator: ';'
+      },
+      dist: {
+        src: ['src/**/*.js'],
+        dest: 'dist/<%= pkg.name %>.js'
+      }
+    },
+    jsdoc : {
+        dist : {
+            src: ['src/*.js', './README'], 
+            options: {
+              destination: 'doc'
+            }
+        }
+    },
+    uglify: {
+      options: {
+        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
+      },
+      dist: {
+        files: {
+          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
+        }
+      }
+    },
+    qunit: {
+      all: {
+        options: {
+          urls: [
+            'http://localhost:8088/test.html'
+          ]
+        }
+      }
+    },
+    jshint: {
+      files: ['Gruntfile.js', 'src/**/*.js', 'test/*.js'],
+      options: {
+        // options here to override JSHint defaults
+        globals: {
+          jQuery: true,
+          console: true,
+          module: true,
+          document: true
+        }
+      }
+    },
+  });
+
+  grunt.loadNpmTasks('grunt-contrib-uglify');
+  grunt.loadNpmTasks('grunt-contrib-jshint');
+  grunt.loadNpmTasks('grunt-contrib-qunit');
+  grunt.loadNpmTasks('grunt-contrib-concat');
+  grunt.loadNpmTasks('grunt-jsdoc');
+
+  grunt.registerTask('test', ['jshint', 'qunit']);
+  grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify', 'jsdoc']);
+};
\ No newline at end of file
diff --git a/lib/js/README b/lib/js/README
index fafdc43..98a1b54 100644
--- a/lib/js/README
+++ b/lib/js/README
@@ -1,8 +1,10 @@
 Thrift Javascript Library
+=========================
+This browser based Apache Thrift implementation supports
+RPC using the JSON protocol over Http[s] with XHR.
 
 License
-=======
-
+-------
 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
@@ -20,21 +22,53 @@
 specific language governing permissions and limitations
 under the License.
 
-Using Thrift with Javascript
-=====================
+Example
+-------
+The listing below demonstrates a simple browser based JavaScript
+Thrift client and Node.js JavaScript server for the HelloSvc service. 
 
-Allows javascript client interfaces to Thrift services.
-This is geared for use in a web browser.
+### hello.thrift - Service IDL
+    service HelloSvc {
+        string hello_func(),
+    }
 
-This client can only speak the JSON Protocol and the only supported
-transport is AJAX.
+### hello.html - Browser Client
+    <!doctype html>
+    <html lang="en">
+    <head>
+        <script src="thrift.js" type="text/javascript"></script>
+        <script src="gen-js/HelloSvc.js" type="text/javascript"></script>
+    </head>
+    <body>
+        <h1>Apache Thrift JavaScript Browser Client Demo</h1>
+        <button id="btn">Get Message from Node Server</button>
+        <script type="text/javascript">
+            document.getElementById("btn").addEventListener("click", getMessage, false);
+    
+            function getMessage() {
+                var transport = new Thrift.Transport("http://localhost:8585");
+                var protocol  = new Thrift.Protocol(transport);
+                var client = new HelloSvcClient(protocol);
+                var msg = client.hello_func();
+                document.getElementById("output").innerHTML = msg;
+            }
+        </script>
+        <h2>Server Response: <div id="output"></div></h2>
+    </body> 
+    </html>
 
-There is a test httpd service in the test dir that requires
-http://hc.apache.org under test dir
-
-Dependencies
-============
-A JavaScript enabled browser. Tested with:
- *IE 6,7,8
- *FF 2,3
- *Safari 3 & 4
+### hello.js - Node Server
+    var thrift = require('thrift');
+    var TJSONProtocol = require('thrift/protocol').TJSONProtocol;
+    var HelloSvc = require('./gen-nodejs/HelloSvc.js');
+    
+    var call_counter = 0;
+        
+    var server = thrift.createHttpGetPostServer(HelloSvc, {
+      hello_func: function(result) {
+        console.log("Client call: " + (++call_counter));
+        result(null, "Hello Apache Thrift for JavaScript " + call_counter);
+      }
+    }, {protocol: TJSONProtocol});
+    
+    server.listen(8585);
\ No newline at end of file
diff --git a/lib/js/package.json b/lib/js/package.json
new file mode 100644
index 0000000..5a8485b
--- /dev/null
+++ b/lib/js/package.json
@@ -0,0 +1,12 @@
+{
+  "name": "thrift",
+  "version": "1.0.0",
+  "devDependencies": {
+    "grunt": "~0.4.1",
+    "grunt-contrib-uglify": "~0.2.2",
+    "grunt-contrib-jshint": "~0.6.3",
+    "grunt-contrib-qunit": "~0.2.2",
+    "grunt-contrib-concat": "~0.3.0",
+    "grunt-jsdoc": "~0.4.0"
+  }
+}
\ No newline at end of file
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';
+    }
+};
diff --git a/lib/js/test/build.xml b/lib/js/test/build.xml
index 53bec58..e302ea0 100755
--- a/lib/js/test/build.xml
+++ b/lib/js/test/build.xml
@@ -100,7 +100,7 @@
     <get src="http://code.jquery.com/qunit/qunit-1.5.0.js" dest="${build}/js/lib/qunit.js" usetimestamp="true"/>
     <get src="http://code.jquery.com/qunit/qunit-1.5.0.css" dest="${build}/js/lib/qunit.css" usetimestamp="true"/>
     <!-- js-test-driver has issues with relative path...so we need a copy -->
-    <copy file="../thrift.js" todir="${build}/js/"/>
+    <copy file="../src/thrift.js" todir="${build}/js/"/>
   </target>
 
   <target name="compile" description="compile the test suite" depends="init, generate, resolve">
@@ -216,7 +216,7 @@
     <jsl:jslint options="evil,forin,browser,bitwise,regexp,newcap,immed" encoding="UTF-8">
       <formatter type="plain" />
       <fileset dir="${genjs}" includes="**/*.js" />
-      <fileset dir=".." includes="thrift.js" />
+      <fileset dir="../src" includes="thrift.js" />
 
       <!-- issues with unsafe character -->
       <!-- fileset dir="." includes="*test*.js" /> -->
@@ -234,7 +234,7 @@
     <exec executable="gjslint" failifexecutionfails="no">
       <arg line="--nojsdoc"/>
       <arg line="${genjs}/*.js"/>
-      <arg line="../thrift.js"/>
+      <arg line="../src/thrift.js"/>
 
       <!-- issues with unsafe character, etc. -->
       <!-- <arg line="*test*.js"/> -->
diff --git a/lib/js/test/phantomjs-qunit.js b/lib/js/test/phantomjs-qunit.js
index d52b522..027be40 100755
--- a/lib/js/test/phantomjs-qunit.js
+++ b/lib/js/test/phantomjs-qunit.js
@@ -1,3 +1,5 @@
+/*jshint evil:true*/
+
 /* This file is only used by the test suite.
  *
  * Origin:  https://github.com/ariya/phantomjs/blob/master/examples/run-qunit.js
@@ -35,12 +37,16 @@
                 } else {
                     // Condition fulfilled (timeout and/or condition is 'true')
                     console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
-                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
+                    if (typeof(onReady) === "string") {
+                        eval(onReady);
+                    } else {
+                        onReady(); //< Do what it's supposed to do once the condition is fulfilled
+                    }  
                     clearInterval(interval); //< Stop this interval
                 }
             }
         }, 100); //< repeat check every 250ms
-};
+}
 
 
 if (phantom.args.length === 0 || phantom.args.length > 2) {
diff --git a/lib/js/test/test.html b/lib/js/test/test.html
index 1c8fc9a..93894c7 100755
--- a/lib/js/test/test.html
+++ b/lib/js/test/test.html
@@ -22,7 +22,7 @@
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>Thrift Javascript Bindings: Unit Test</title>
 
-  <script src="/thrift.js"                  type="text/javascript" charset="utf-8"></script>
+  <script src="/src/thrift.js"                  type="text/javascript" charset="utf-8"></script>
   <script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
   <script src="gen-js/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>
 
diff --git a/lib/js/test/test.js b/lib/js/test/test.js
index 99fcc41..b0904a9 100755
--- a/lib/js/test/test.js
+++ b/lib/js/test/test.js
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
- 
+ /* jshint -W100 */
  
 /*
  * JavaScript test suite
@@ -401,6 +401,8 @@
     .error(function(xhr, status, e){
       equal(e.errorCode, 1001);
       equal(e.message, "Xception");
-      QUnit.start();
+      //QUnit.start();
+      //Note start is not required here because:
+      //$(document).ajaxError( function() { QUnit.start(); } );
     });
   });
diff --git a/lib/js/thrift.js b/lib/js/thrift.js
deleted file mode 100644
index e59f07f..0000000
--- a/lib/js/thrift.js
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * 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.
- */
-var Thrift = {
-    Version: '1.0.0-dev',
-/*
-    Description: 'JavaScript bindings for the Apache Thrift RPC system',
-    License: 'http://www.apache.org/licenses/LICENSE-2.0',
-    Homepage: 'http://thrift.apache.org',
-    BugReports: 'https://issues.apache.org/jira/browse/THRIFT',
-    Maintainer: 'dev@thrift.apache.org',
-*/
-
-    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
-    },
-
-    MessageType: {
-        'CALL' : 1,
-        'REPLY' : 2,
-        'EXCEPTION' : 3
-    },
-
-    objectLength: function(obj) {
-        var length = 0;
-        for (var k in obj) {
-            if (obj.hasOwnProperty(k)) {
-                length++;
-            }
-        }
-
-        return length;
-    },
-
-    inherits: function(constructor, superConstructor) {
-      //Prototypal Inheritance http://javascript.crockford.com/prototypal.html
-      function F() {}
-      F.prototype = superConstructor.prototype;
-      constructor.prototype = new F();
-    }
-};
-
-
-
-Thrift.TException = function(message) {
-    this.message = message;
-};
-Thrift.inherits(Thrift.TException, Error);
-Thrift.TException.prototype.name = 'TException';
-
-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
-};
-
-Thrift.TApplicationException = function(message, code) {
-    this.message = message;
-    this.code = (code === null) ? 0 : code;
-};
-Thrift.inherits(Thrift.TApplicationException, Thrift.TException);
-Thrift.TApplicationException.prototype.name = 'TApplicationException';
-
-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();
-};
-
-Thrift.TApplicationException.prototype.write = function(output) {
-    var xfer = 0;
-
-    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();
-};
-
-Thrift.TApplicationException.prototype.getCode = function() {
-    return this.code;
-};
-
-Thrift.TApplicationException.prototype.getMessage = function() {
-    return this.message;
-};
-
-/**
- *If you do not specify a url then you must handle ajax on your own.
- *This is how to use js bindings in a async fashion.
- */
-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
-    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 the XmlHttpRequest object.";
-    },
-
-    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;
-    },
-
-    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;
-    },
-
-    setRecvBuffer: function(buf) {
-        this.recv_buf = buf;
-        this.recv_buf_sz = this.recv_buf.length;
-        this.wpos = this.recv_buf.length;
-        this.rpos = 0;
-    },
-
-    isOpen: function() {
-        return true;
-    },
-
-    open: function() {},
-
-    close: function() {},
-
-    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;
-    },
-
-    readAll: function() {
-        return this.recv_buf;
-    },
-
-    write: function(buf) {
-        this.send_buf = buf;
-    },
-
-    getSendBuffer: function() {
-        return this.send_buf;
-    }
-
-};
-
-
-
-Thrift.Protocol = function(transport) {
-    this.transport = transport;
-};
-
-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.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;
-
-Thrift.Protocol.Version = 1;
-
-Thrift.Protocol.prototype = {
-
-    getTransport: function() {
-        return this.transport;
-    },
-
-    //Write functions
-    writeMessageBegin: function(name, messageType, seqid) {
-        this.tstack = [];
-        this.tpos = [];
-
-        this.tstack.push([Thrift.Protocol.Version, '"' +
-            name + '"', messageType, seqid]);
-    },
-
-    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);
-     },
-
-
-    writeStructBegin: function(name) {
-        this.tpos.push(this.tstack.length);
-        this.tstack.push({});
-    },
-
-    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;
-    },
-
-    writeFieldBegin: function(name, fieldType, fieldId) {
-        this.tpos.push(this.tstack.length);
-        this.tstack.push({ 'fieldId': '"' +
-            fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType]
-        });
-
-    },
-
-    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();
-    },
-
-    writeFieldStop: function() {
-        //na
-    },
-
-    writeMapBegin: function(keyType, valType, size) {
-        //size is invalid, we'll set it on end.
-        this.tpos.push(this.tstack.length);
-        this.tstack.push([Thrift.Protocol.Type[keyType],
-            Thrift.Protocol.Type[valType], 0]);
-    },
-
-    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(',') + ']';
-    },
-
-    writeListBegin: function(elemType, size) {
-        this.tpos.push(this.tstack.length);
-        this.tstack.push([Thrift.Protocol.Type[elemType], size]);
-    },
-
-    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(',') + ']';
-    },
-
-    writeSetBegin: function(elemType, size) {
-        this.tpos.push(this.tstack.length);
-        this.tstack.push([Thrift.Protocol.Type[elemType], size]);
-    },
-
-    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(',') + ']';
-    },
-
-    writeBool: function(value) {
-        this.tstack.push(value ? 1 : 0);
-    },
-
-    writeByte: function(i8) {
-        this.tstack.push(i8);
-    },
-
-    writeI16: function(i16) {
-        this.tstack.push(i16);
-    },
-
-    writeI32: function(i32) {
-        this.tstack.push(i32);
-    },
-
-    writeI64: function(i64) {
-        this.tstack.push(i64);
-    },
-
-    writeDouble: function(dbl) {
-        this.tstack.push(dbl);
-    },
-
-    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 + '"');
-        }
-    },
-
-    writeBinary: function(str) {
-        this.writeString(str);
-    },
-
-
-
-    // Reading functions
-    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;
-    },
-
-    readMessageEnd: function() {
-    },
-
-    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;
-    },
-
-    readStructEnd: function() {
-        if (this.rstack[this.rstack.length - 2] instanceof Array) {
-            this.rstack.pop();
-        }
-    },
-
-    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;
-    },
-
-    readFieldEnd: function() {
-        var pos = this.rpos.pop();
-
-        //get back to the right place in the stack
-        while (this.rstack.length > pos) {
-            this.rstack.pop();
-        }
-
-    },
-
-    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;
-    },
-
-    readMapEnd: function() {
-        this.readFieldEnd();
-    },
-
-    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;
-    },
-
-    readListEnd: function() {
-        this.readFieldEnd();
-    },
-
-    readSetBegin: function(elemType, size) {
-        return this.readListBegin(elemType, size);
-    },
-
-    readSetEnd: function() {
-        return this.readListEnd();
-    },
-
-    readBool: function() {
-        var r = this.readI32();
-
-        if (r !== null && r.value == '1') {
-            r.value = true;
-        } else {
-            r.value = false;
-        }
-
-        return r;
-    },
-
-    readByte: function() {
-        return this.readI32();
-    },
-
-    readI16: function() {
-        return this.readI32();
-    },
-
-    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;
-    },
-
-    readI64: function() {
-        return this.readI32();
-    },
-
-    readDouble: function() {
-        return this.readI32();
-    },
-
-    readString: function() {
-        var r = this.readI32();
-        return r;
-    },
-
-    readBinary: function() {
-        return this.readString();
-    },
-
-
-    //Method to arbitrarily skip over data.
-    skip: function(type) {
-        throw 'skip not supported yet';
-    }
-};
