THRIFT-1615 PHP Namespace (was Thrift for Symfony 2)
Patch: Xavier HAUSHERR


git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1381323 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/php/Makefile.am b/lib/php/Makefile.am
index b317197..5c4d0f4 100755
--- a/lib/php/Makefile.am
+++ b/lib/php/Makefile.am
@@ -34,29 +34,62 @@
 phpmodule_SCRIPTS = src/ext/thrift_protocol/modules/thrift_protocol.so
 endif
 
-phpdir = $(PHP_PREFIX)
-php_DATA =  \
-  src/autoload.php \
-  src/Thrift.php
+phpdir = $(PHP_PREFIX)/Thrift
 
-phpprotocoldir = $(phpdir)/protocol
+phpbasedir = $(phpdir)/Base
+phpbase_DATA = \
+  lib/Thrift/Base/TBase.php
+
+phpexceptiondir = $(phpdir)/Exception
+phpexception_DATA = \
+  lib/Thrift/Exception/TApplicationException.php \
+  lib/Thrift/Exception/TException.php \
+  lib/Thrift/Exception/TProtocolException.php \
+  lib/Thrift/Exception/TTransportException.php
+
+phpfactorydir = $(phpdir)/Factory
+phpfactory_DATA = \
+  lib/Thrift/Factory/TBinaryProtocolFactory.php \
+  lib/Thrift/Factory/TCompactProtocolFactory.php \
+  lib/Thrift/Factory/TJSONProtocolFactory.php \
+  lib/Thrift/Factory/TProtocolFactory.php \
+  lib/Thrift/Factory/TTransportFactory.php
+
+phpprotocoldir = $(phpdir)/Protocol
 phpprotocol_DATA = \
-  src/protocol/TBinaryProtocol.php \
-  src/protocol/TBinarySerializer.php \
-  src/protocol/TProtocol.php \
-  src/protocol/TJSONProtocol.php
+  lib/Thrift/Protocol/TBinaryProtocolAccelerated.php \
+  lib/Thrift/Protocol/TBinaryProtocol.php \
+  lib/Thrift/Protocol/TCompactProtocol.php \
+  lib/Thrift/Protocol/TJSONProtocol.php \
+  lib/Thrift/Protocol/TProtocol.php
 
-phptransportdir = $(phpdir)/transport
+phpprotocoljsondir = $(phpprotocoldir)/JSON
+phpprotocoljson_DATA = \
+  lib/Thrift/Protocol/JSON/BaseContext.php \
+  lib/Thrift/Protocol/JSON/ListContext.php \
+  lib/Thrift/Protocol/JSON/LookaheadReader.php \
+  lib/Thrift/Protocol/JSON/PairContext.php
+
+phpserializerdir = $(phpdir)/Serializer
+phpserializer_DATA = \
+  lib/Thrift/Serializer/TBinarySerializer.php
+
+phptransportdir = $(phpdir)/Transport
 phptransport_DATA = \
-  src/transport/TBufferedTransport.php \
-  src/transport/TFramedTransport.php \
-  src/transport/THttpClient.php \
-  src/transport/TMemoryBuffer.php \
-  src/transport/TNullTransport.php \
-  src/transport/TPhpStream.php \
-  src/transport/TSocket.php \
-  src/transport/TSocketPool.php \
-  src/transport/TTransport.php
+  lib/Thrift/Transport/TBufferedTransport.php \
+  lib/Thrift/Transport/TFramedTransport.php \
+  lib/Thrift/Transport/THttpClient.php \
+  lib/Thrift/Transport/TMemoryBuffer.php \
+  lib/Thrift/Transport/TNullTransport.php \
+  lib/Thrift/Transport/TPhpStream.php \
+  lib/Thrift/Transport/TSocket.php \
+  lib/Thrift/Transport/TSocketPool.php \
+  lib/Thrift/Transport/TTransport.php
+
+phptypedir = $(phpdir)/Type
+phptype_DATA = \
+  lib/Thrift/Type/TMessageType.php \
+  lib/Thrift/Type/TType.php
 
 EXTRA_DIST = src thrift_protocol.ini README.apache
 
diff --git a/lib/php/README b/lib/php/README
index bb566f4..af6cf88 100644
--- a/lib/php/README
+++ b/lib/php/README
@@ -29,24 +29,14 @@
 
 To use Thrift in your PHP codebase, take the following steps:
 
-#1) Copy all of thrift/lib/php/src into your PHP codebase
-#2) Set $GLOBALS['THRIFT_ROOT'] to the path you installed Thrift
-#3) include_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
+#1) Copy all of thrift/lib/php/lib into your PHP codebase
+#2) Configure Symfony Autoloader (or whatever you usually use)
 
-Note that #3 must be done before including any other Thrift files.
-If you do not do #2, Thrift.php will set this global for you, but it will be
-done using dirname(__FILE__), which is less efficient than providing the static
-string yourself.
+After thaht, you have to manually include the Thrift package
+created by the compiler:
 
-When you generate a Thrift package using the compiler, it makes an assumption
-about where your generated code will live. If your file is "MyPackage.thrift",
-the generated files must be installed into:
-
-$GLOBALS['THRIFT_ROOT'].'/packages/MyPackage/';
-
-This allows the code generator to compile your code without any extra flags
-for the target directory names while still allowing your include paths to
-be absolute (if you have an absolute THRIFT_ROOT).
+require_once 'packages/Service/Service.php';
+require_once 'packages/Service/Types.php';
 
 Dependencies
 ============
diff --git a/lib/php/README.apache b/lib/php/README.apache
index 8c41833..5e92589 100644
--- a/lib/php/README.apache
+++ b/lib/php/README.apache
@@ -32,18 +32,30 @@
 
 <?php
 
+namespace MyNamespace;
+
+/**
+ * Include path
+ */
+$THRIFT_ROOT = '/your/thrift/root/lib';
+
+/**
+ * Init Autloader
+ */
+require_once $THRIFT_ROOT . '/Thrift/ClassLoader/ThriftClassLoader.php';
+
+$loader = new ThriftClassLoader();
+$loader->registerNamespace('Thrift', $THRIFT_ROOT);
+$loader->registerDefinition('Thrift', $THRIFT_ROOT . '/packages');
+$loader->register();
+
+use Thrift\Transport\TPhpStream;
+use Thrift\Protocol\TBinaryProtocol;
+
 /**
  * Example of how to build a Thrift server in Apache/PHP
- *
  */
 
-$GLOBALS['THRIFT_ROOT'] = '/your/thrift/root';
-
-include_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/packages/Service/Service.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TPhpStream.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
-
 class ServiceHandler implements ServiceIf {
   // Implement your interface and methods here
 }
diff --git a/lib/php/lib/Thrift/Base/TBase.php b/lib/php/lib/Thrift/Base/TBase.php
new file mode 100644
index 0000000..3d5b526
--- /dev/null
+++ b/lib/php/lib/Thrift/Base/TBase.php
@@ -0,0 +1,367 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Base;
+
+use Thrift\Type\TType;
+
+/**
+ * Base class from which other Thrift structs extend. This is so that we can
+ * cut back on the size of the generated code which is turning out to have a
+ * nontrivial cost just to load thanks to the wondrously abysmal implementation
+ * of PHP. Note that code is intentionally duplicated in here to avoid making
+ * function calls for every field or member of a container..
+ */
+abstract class TBase {
+
+  static $tmethod = array(TType::BOOL   => 'Bool',
+                          TType::BYTE   => 'Byte',
+                          TType::I16    => 'I16',
+                          TType::I32    => 'I32',
+                          TType::I64    => 'I64',
+                          TType::DOUBLE => 'Double',
+                          TType::STRING => 'String');
+
+  abstract function read($input);
+
+  abstract function write($output);
+
+  public function __construct($spec=null, $vals=null) {
+    if (is_array($spec) && is_array($vals)) {
+      foreach ($spec as $fid => $fspec) {
+        $var = $fspec['var'];
+        if (isset($vals[$var])) {
+          $this->$var = $vals[$var];
+        }
+      }
+    }
+  }
+
+  public function __wakeup()
+  {
+    $this->__construct(get_object_vars($this));
+  }
+
+  private function _readMap(&$var, $spec, $input) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kread = $vread = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kread = 'read'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vread = 'read'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $var = array();
+    $_ktype = $_vtype = $size = 0;
+    $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
+    for ($i = 0; $i < $size; ++$i) {
+      $key = $val = null;
+      if ($kread !== null) {
+        $xfer += $input->$kread($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $class = $kspec['class'];
+          $key = new $class();
+          $xfer += $key->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($key, $kspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($key, $kspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($key, $kspec, $input, true);
+          break;
+        }
+      }
+      if ($vread !== null) {
+        $xfer += $input->$vread($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $class = $vspec['class'];
+          $val = new $class();
+          $xfer += $val->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($val, $vspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($val, $vspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($val, $vspec, $input, true);
+          break;
+        }
+      }
+      $var[$key] = $val;
+    }
+    $xfer += $input->readMapEnd();
+    return $xfer;
+  }
+
+  private function _readList(&$var, $spec, $input, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $eread = $vread = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $eread = 'read'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    $var = array();
+    $_etype = $size = 0;
+    if ($set) {
+      $xfer += $input->readSetBegin($_etype, $size);
+    } else {
+      $xfer += $input->readListBegin($_etype, $size);
+    }
+    for ($i = 0; $i < $size; ++$i) {
+      $elem = null;
+      if ($eread !== null) {
+        $xfer += $input->$eread($elem);
+      } else {
+        $espec = $spec['elem'];
+        switch ($etype) {
+        case TType::STRUCT:
+          $class = $espec['class'];
+          $elem = new $class();
+          $xfer += $elem->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($elem, $espec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($elem, $espec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($elem, $espec, $input, true);
+          break;
+        }
+      }
+      if ($set) {
+        $var[$elem] = true;
+      } else {
+        $var []= $elem;
+      }
+    }
+    if ($set) {
+      $xfer += $input->readSetEnd();
+    } else {
+      $xfer += $input->readListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _read($class, $spec, $input) {
+    $xfer = 0;
+    $fname = null;
+    $ftype = 0;
+    $fid = 0;
+    $xfer += $input->readStructBegin($fname);
+    while (true) {
+      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+      if ($ftype == TType::STOP) {
+        break;
+      }
+      if (isset($spec[$fid])) {
+        $fspec = $spec[$fid];
+        $var = $fspec['var'];
+        if ($ftype == $fspec['type']) {
+          $xfer = 0;
+          if (isset(TBase::$tmethod[$ftype])) {
+            $func = 'read'.TBase::$tmethod[$ftype];
+            $xfer += $input->$func($this->$var);
+          } else {
+            switch ($ftype) {
+            case TType::STRUCT:
+              $class = $fspec['class'];
+              $this->$var = new $class();
+              $xfer += $this->$var->read($input);
+              break;
+            case TType::MAP:
+              $xfer += $this->_readMap($this->$var, $fspec, $input);
+              break;
+            case TType::LST:
+              $xfer += $this->_readList($this->$var, $fspec, $input, false);
+              break;
+            case TType::SET:
+              $xfer += $this->_readList($this->$var, $fspec, $input, true);
+              break;
+            }
+          }
+        } else {
+          $xfer += $input->skip($ftype);
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      $xfer += $input->readFieldEnd();
+    }
+    $xfer += $input->readStructEnd();
+    return $xfer;
+  }
+
+  private function _writeMap($var, $spec, $output) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kwrite = $vwrite = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kwrite = 'write'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vwrite = 'write'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
+    foreach ($var as $key => $val) {
+      if (isset($kwrite)) {
+        $xfer += $output->$kwrite($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $xfer += $key->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($key, $kspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($key, $kspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($key, $kspec, $output, true);
+          break;
+        }
+      }
+      if (isset($vwrite)) {
+        $xfer += $output->$vwrite($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $xfer += $val->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($val, $vspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($val, $vspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($val, $vspec, $output, true);
+          break;
+        }
+      }
+    }
+    $xfer += $output->writeMapEnd();
+    return $xfer;
+  }
+
+  private function _writeList($var, $spec, $output, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $ewrite = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $ewrite = 'write'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    if ($set) {
+      $xfer += $output->writeSetBegin($etype, count($var));
+    } else {
+      $xfer += $output->writeListBegin($etype, count($var));
+    }
+    foreach ($var as $key => $val) {
+      $elem = $set ? $key : $val;
+      if (isset($ewrite)) {
+        $xfer += $output->$ewrite($elem);
+      } else {
+        switch ($etype) {
+        case TType::STRUCT:
+          $xfer += $elem->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($elem, $espec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($elem, $espec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($elem, $espec, $output, true);
+          break;
+        }
+      }
+    }
+    if ($set) {
+      $xfer += $output->writeSetEnd();
+    } else {
+      $xfer += $output->writeListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _write($class, $spec, $output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin($class);
+    foreach ($spec as $fid => $fspec) {
+      $var = $fspec['var'];
+      if ($this->$var !== null) {
+        $ftype = $fspec['type'];
+        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
+        if (isset(TBase::$tmethod[$ftype])) {
+          $func = 'write'.TBase::$tmethod[$ftype];
+          $xfer += $output->$func($this->$var);
+        } else {
+          switch ($ftype) {
+          case TType::STRUCT:
+            $xfer += $this->$var->write($output);
+            break;
+          case TType::MAP:
+            $xfer += $this->_writeMap($this->$var, $fspec, $output);
+            break;
+          case TType::LST:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, false);
+            break;
+          case TType::SET:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, true);
+            break;
+          }
+        }
+        $xfer += $output->writeFieldEnd();
+      }
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+}
diff --git a/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php b/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php
new file mode 100644
index 0000000..bce93f5
--- /dev/null
+++ b/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php
@@ -0,0 +1,223 @@
+<?php
+/*
+ * 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.
+ *
+ * ClassLoader to load Thrift library and definitions
+ * Inspired from UniversalClassLoader from Symfony 2 
+ *
+ * @package thrift.classloader
+ */
+
+namespace Thrift\ClassLoader;
+
+class ThriftClassLoader
+{
+    /**
+     * Namespaces path
+     * @var array
+     */
+    protected $namespaces = array();
+
+    /**
+     * Thrift definition paths
+     * @var type
+     */
+    protected $definitions = array();
+
+    /**
+     * Do we use APC cache ?
+     * @var boolean
+     */
+    protected $apc = false;
+
+    /**
+     * APC Cache prefix
+     * @var string
+     */
+    protected $apc_prefix;
+
+    /**
+     * Set autoloader to use APC cache
+     * @param boolean $apc
+     * @param string $apc_prefix
+     */
+    public function __construct($apc = false, $apc_prefix = null)
+    {
+        $this->apc = $apc;
+        $this->apc_prefix = $apc_prefix;
+    }
+
+    /**
+     * Registers a namespace.
+     *
+     * @param string       $namespace The namespace
+     * @param array|string $paths     The location(s) of the namespace
+     */
+    public function registerNamespace($namespace, $paths)
+    {
+        $this->namespaces[$namespace] = (array) $paths;
+    }
+
+    /**
+     * Registers a Thrift definition namespace.
+     *
+     * @param string       $namespace The definition namespace
+     * @param array|string $paths     The location(s) of the definition namespace
+     */
+    public function registerDefinition($namespace, $paths)
+    {
+        $this->definitions[$namespace] = (array) $paths;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param Boolean $prepend Whether to prepend the autoloader or not
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+    }
+
+    /**
+     * Loads the given class, definition or interface.
+     *
+     * @param string $class The name of the class
+     */
+    public function loadClass($class)
+    {
+        if (
+            (true === $this->apc && ($file = $this->findFileInApc($class))) or
+            ($file = $this->findFile($class))
+        )
+        {
+            require_once $file;
+        }
+    }
+
+    /**
+     * Loads the given class or interface in APC.
+     * @param string $class The name of the class
+     * @return string
+     */
+    protected function findFileInApc($class)
+    {
+        if (false === $file = apc_fetch($this->apc_prefix.$class)) {
+            apc_store($this->apc_prefix.$class, $file = $this->findFile($class));
+        }
+
+        return $file;
+    }
+
+    /**
+     * Find class in namespaces or definitions directories
+     * @param string $class
+     * @return string
+     */
+    public function findFile($class)
+    {
+        // Remove first backslash
+        if ('\\' == $class[0])
+        {
+            $class = substr($class, 1);
+        }
+
+        if (false !== $pos = strrpos($class, '\\'))
+        {
+            // Namespaced class name
+            $namespace = substr($class, 0, $pos);
+
+            // Iterate in normal namespaces
+            foreach ($this->namespaces as $ns => $dirs)
+            {
+                //Don't interfere with other autoloaders
+                if (0 !== strpos($namespace, $ns))
+                {
+                    continue;
+                }
+
+                foreach ($dirs as $dir)
+                {
+                    $className = substr($class, $pos + 1);
+
+                    $file = $dir.DIRECTORY_SEPARATOR.
+                                 str_replace('\\', DIRECTORY_SEPARATOR, $namespace).
+                                 DIRECTORY_SEPARATOR.
+                                 $className.'.php';
+
+                    if (file_exists($file))
+                    {
+                        return $file;
+                    }
+                }
+            }
+
+            // Iterate in Thrift namespaces
+
+            // Remove first part of namespace
+            $m = explode('\\', $class);
+
+            // Ignore wrong call
+            if(count($m) <= 1)
+            {
+                return;
+            }
+
+            $class = array_pop($m);
+            $namespace = implode('\\', $m);
+
+            foreach ($this->definitions as $ns => $dirs)
+            {
+                //Don't interfere with other autoloaders
+                if (0 !== strpos($namespace, $ns))
+                {
+                    continue;
+                }
+
+                foreach ($dirs as $dir)
+                {
+                    /**
+                     * Available in service: Interface, Client, Processor, Rest
+                     * And every service methods (_.+)
+                     */
+                    if(
+                        0 === preg_match('#(.+)(if|client|processor|rest)$#i', $class, $n) and
+                        0 === preg_match('#(.+)_[a-z0-9]+_(args|result)$#i', $class, $n)
+                    )
+                    {
+                        $className = 'Types';
+                    }
+                    else
+                    {
+                        $className = $n[1];
+                    }
+
+                    $file = $dir.DIRECTORY_SEPARATOR .
+                                 str_replace('\\', DIRECTORY_SEPARATOR, $namespace) .
+                                 DIRECTORY_SEPARATOR .
+                                 $className . '.php';
+
+                    if (file_exists($file))
+                    {
+                        return $file;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/lib/php/lib/Thrift/Exception/TApplicationException.php b/lib/php/lib/Thrift/Exception/TApplicationException.php
new file mode 100644
index 0000000..55d46e6
--- /dev/null
+++ b/lib/php/lib/Thrift/Exception/TApplicationException.php
@@ -0,0 +1,69 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Exception\TException;
+use Thrift\Type\TType;
+
+class TApplicationException extends TException {
+  static $_TSPEC =
+    array(1 => array('var' => 'message',
+                     'type' => TType::STRING),
+          2 => array('var' => 'code',
+                     'type' => TType::I32));
+
+  const UNKNOWN = 0;
+  const UNKNOWN_METHOD = 1;
+  const INVALID_MESSAGE_TYPE = 2;
+  const WRONG_METHOD_NAME = 3;
+  const BAD_SEQUENCE_ID = 4;
+  const MISSING_RESULT = 5;
+  const INTERNAL_ERROR = 6;
+  const PROTOCOL_ERROR = 7;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+
+  public function read($output) {
+    return $this->_read('TApplicationException', self::$_TSPEC, $output);
+  }
+
+  public function write($output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin('TApplicationException');
+    if ($message = $this->getMessage()) {
+      $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
+      $xfer += $output->writeString($message);
+      $xfer += $output->writeFieldEnd();
+    }
+    if ($code = $this->getCode()) {
+      $xfer += $output->writeFieldBegin('type', TType::I32, 2);
+      $xfer += $output->writeI32($code);
+      $xfer += $output->writeFieldEnd();
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+}
diff --git a/lib/php/lib/Thrift/Exception/TException.php b/lib/php/lib/Thrift/Exception/TException.php
new file mode 100644
index 0000000..8e8cd28
--- /dev/null
+++ b/lib/php/lib/Thrift/Exception/TException.php
@@ -0,0 +1,369 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Type\TType;
+use Thrift\Base\TBase;
+
+/**
+ * NOTE(mcslee): This currently contains a ton of duplicated code from TBase
+ * because we need to save CPU cycles and this is not yet in an extension.
+ * Ideally we'd multiply-inherit TException from both Exception and Base, but
+ * that's not possible in PHP and there are no modules either, so for now we
+ * apologetically take a trip to HackTown.
+ *
+ * Can be called with standard Exception constructor (message, code) or with
+ * Thrift Base object constructor (spec, vals).
+ *
+ * @param mixed $p1 Message (string) or type-spec (array)
+ * @param mixed $p2 Code (integer) or values (array)
+ */
+class TException extends \Exception {
+  function __construct($p1=null, $p2=0) {
+    if (is_array($p1) && is_array($p2)) {
+      $spec = $p1;
+      $vals = $p2;
+      foreach ($spec as $fid => $fspec) {
+        $var = $fspec['var'];
+        if (isset($vals[$var])) {
+          $this->$var = $vals[$var];
+        }
+      }
+    } else {
+      parent::__construct($p1, $p2);
+    }
+  }
+
+  static $tmethod = array(TType::BOOL   => 'Bool',
+                          TType::BYTE   => 'Byte',
+                          TType::I16    => 'I16',
+                          TType::I32    => 'I32',
+                          TType::I64    => 'I64',
+                          TType::DOUBLE => 'Double',
+                          TType::STRING => 'String');
+
+  private function _readMap(&$var, $spec, $input) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kread = $vread = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kread = 'read'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vread = 'read'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $var = array();
+    $_ktype = $_vtype = $size = 0;
+    $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
+    for ($i = 0; $i < $size; ++$i) {
+      $key = $val = null;
+      if ($kread !== null) {
+        $xfer += $input->$kread($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $class = $kspec['class'];
+          $key = new $class();
+          $xfer += $key->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($key, $kspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($key, $kspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($key, $kspec, $input, true);
+          break;
+        }
+      }
+      if ($vread !== null) {
+        $xfer += $input->$vread($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $class = $vspec['class'];
+          $val = new $class();
+          $xfer += $val->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($val, $vspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($val, $vspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($val, $vspec, $input, true);
+          break;
+        }
+      }
+      $var[$key] = $val;
+    }
+    $xfer += $input->readMapEnd();
+    return $xfer;
+  }
+
+  private function _readList(&$var, $spec, $input, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $eread = $vread = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $eread = 'read'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    $var = array();
+    $_etype = $size = 0;
+    if ($set) {
+      $xfer += $input->readSetBegin($_etype, $size);
+    } else {
+      $xfer += $input->readListBegin($_etype, $size);
+    }
+    for ($i = 0; $i < $size; ++$i) {
+      $elem = null;
+      if ($eread !== null) {
+        $xfer += $input->$eread($elem);
+      } else {
+        $espec = $spec['elem'];
+        switch ($etype) {
+        case TType::STRUCT:
+          $class = $espec['class'];
+          $elem = new $class();
+          $xfer += $elem->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($elem, $espec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($elem, $espec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($elem, $espec, $input, true);
+          break;
+        }
+      }
+      if ($set) {
+        $var[$elem] = true;
+      } else {
+        $var []= $elem;
+      }
+    }
+    if ($set) {
+      $xfer += $input->readSetEnd();
+    } else {
+      $xfer += $input->readListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _read($class, $spec, $input) {
+    $xfer = 0;
+    $fname = null;
+    $ftype = 0;
+    $fid = 0;
+    $xfer += $input->readStructBegin($fname);
+    while (true) {
+      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+      if ($ftype == TType::STOP) {
+        break;
+      }
+      if (isset($spec[$fid])) {
+        $fspec = $spec[$fid];
+        $var = $fspec['var'];
+        if ($ftype == $fspec['type']) {
+          $xfer = 0;
+          if (isset(TBase::$tmethod[$ftype])) {
+            $func = 'read'.TBase::$tmethod[$ftype];
+            $xfer += $input->$func($this->$var);
+          } else {
+            switch ($ftype) {
+            case TType::STRUCT:
+              $class = $fspec['class'];
+              $this->$var = new $class();
+              $xfer += $this->$var->read($input);
+              break;
+            case TType::MAP:
+              $xfer += $this->_readMap($this->$var, $fspec, $input);
+              break;
+            case TType::LST:
+              $xfer += $this->_readList($this->$var, $fspec, $input, false);
+              break;
+            case TType::SET:
+              $xfer += $this->_readList($this->$var, $fspec, $input, true);
+              break;
+            }
+          }
+        } else {
+          $xfer += $input->skip($ftype);
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      $xfer += $input->readFieldEnd();
+    }
+    $xfer += $input->readStructEnd();
+    return $xfer;
+  }
+
+  private function _writeMap($var, $spec, $output) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kwrite = $vwrite = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kwrite = 'write'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vwrite = 'write'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
+    foreach ($var as $key => $val) {
+      if (isset($kwrite)) {
+        $xfer += $output->$kwrite($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $xfer += $key->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($key, $kspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($key, $kspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($key, $kspec, $output, true);
+          break;
+        }
+      }
+      if (isset($vwrite)) {
+        $xfer += $output->$vwrite($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $xfer += $val->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($val, $vspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($val, $vspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($val, $vspec, $output, true);
+          break;
+        }
+      }
+    }
+    $xfer += $output->writeMapEnd();
+    return $xfer;
+  }
+
+  private function _writeList($var, $spec, $output, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $ewrite = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $ewrite = 'write'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    if ($set) {
+      $xfer += $output->writeSetBegin($etype, count($var));
+    } else {
+      $xfer += $output->writeListBegin($etype, count($var));
+    }
+    foreach ($var as $key => $val) {
+      $elem = $set ? $key : $val;
+      if (isset($ewrite)) {
+        $xfer += $output->$ewrite($elem);
+      } else {
+        switch ($etype) {
+        case TType::STRUCT:
+          $xfer += $elem->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($elem, $espec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($elem, $espec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($elem, $espec, $output, true);
+          break;
+        }
+      }
+    }
+    if ($set) {
+      $xfer += $output->writeSetEnd();
+    } else {
+      $xfer += $output->writeListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _write($class, $spec, $output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin($class);
+    foreach ($spec as $fid => $fspec) {
+      $var = $fspec['var'];
+      if ($this->$var !== null) {
+        $ftype = $fspec['type'];
+        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
+        if (isset(TBase::$tmethod[$ftype])) {
+          $func = 'write'.TBase::$tmethod[$ftype];
+          $xfer += $output->$func($this->$var);
+        } else {
+          switch ($ftype) {
+          case TType::STRUCT:
+            $xfer += $this->$var->write($output);
+            break;
+          case TType::MAP:
+            $xfer += $this->_writeMap($this->$var, $fspec, $output);
+            break;
+          case TType::LST:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, false);
+            break;
+          case TType::SET:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, true);
+            break;
+          }
+        }
+        $xfer += $output->writeFieldEnd();
+      }
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+
+}
diff --git a/lib/php/lib/Thrift/Exception/TProtocolException.php b/lib/php/lib/Thrift/Exception/TProtocolException.php
new file mode 100644
index 0000000..98a8d9d
--- /dev/null
+++ b/lib/php/lib/Thrift/Exception/TProtocolException.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ * @author: rmarin (marin.radu@facebook.com)
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Exception\TException;
+
+/**
+ * Protocol module. Contains all the types and definitions needed to implement
+ * a protocol encoder/decoder.
+ *
+ * @package thrift.protocol
+ */
+
+/**
+ * Protocol exceptions
+ */
+class TProtocolException extends TException {
+  const UNKNOWN = 0;
+  const INVALID_DATA = 1;
+  const NEGATIVE_SIZE = 2;
+  const SIZE_LIMIT = 3;
+  const BAD_VERSION = 4;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+}
diff --git a/lib/php/lib/Thrift/Exception/TTransportException.php b/lib/php/lib/Thrift/Exception/TTransportException.php
new file mode 100644
index 0000000..f467eb9
--- /dev/null
+++ b/lib/php/lib/Thrift/Exception/TTransportException.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Exception\TException;
+
+/**
+ * Transport exceptions
+ */
+class TTransportException extends TException {
+
+  const UNKNOWN = 0;
+  const NOT_OPEN = 1;
+  const ALREADY_OPEN = 2;
+  const TIMED_OUT = 3;
+  const END_OF_FILE = 4;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Factory/TBinaryProtocolFactory.php b/lib/php/lib/Thrift/Factory/TBinaryProtocolFactory.php
new file mode 100644
index 0000000..85da567
--- /dev/null
+++ b/lib/php/lib/Thrift/Factory/TBinaryProtocolFactory.php
@@ -0,0 +1,43 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Factory;
+
+use Thrift\Factory\TProtocolFactory;
+use Thrift\Protocol\TBinaryProtocol;
+
+/**
+ * Binary Protocol Factory
+ */
+class TBinaryProtocolFactory implements TProtocolFactory {
+  private $strictRead_ = false;
+  private $strictWrite_ = false;
+
+  public function __construct($strictRead=false, $strictWrite=false) {
+    $this->strictRead_ = $strictRead;
+    $this->strictWrite_ = $strictWrite;
+  }
+
+  public function getProtocol($trans) {
+    return new TBinaryProtocol($trans, $this->strictRead_, $this->strictWrite_);
+  }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Factory/TCompactProtocolFactory.php b/lib/php/lib/Thrift/Factory/TCompactProtocolFactory.php
new file mode 100644
index 0000000..9f972aa
--- /dev/null
+++ b/lib/php/lib/Thrift/Factory/TCompactProtocolFactory.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Factory;
+
+use Thrift\Factory\TProtocolFactory;
+use Thrift\Protocol\TCompactProtocol;
+
+/**
+ * Compact Protocol Factory
+ */
+class TCompactProtocolFactory implements TProtocolFactory {
+
+  public function __construct() {
+  }
+
+  public function getProtocol($trans) {
+    return new TCompactProtocol($trans);
+  }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Factory/TJSONProtocolFactory.php b/lib/php/lib/Thrift/Factory/TJSONProtocolFactory.php
new file mode 100644
index 0000000..27e4391
--- /dev/null
+++ b/lib/php/lib/Thrift/Factory/TJSONProtocolFactory.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Factory;
+
+use Thrift\Factory\TProtocolFactory;
+use Thrift\Protocol\TJSONProtocol;
+
+/**
+ * JSON Protocol Factory
+ */
+class TJSONProtocolFactory implements TProtocolFactory
+{
+    public function __construct()
+    {
+    }
+
+    public function getProtocol($trans)
+    {
+        return new TJSONProtocol($trans);
+    }
+}
diff --git a/lib/php/lib/Thrift/Factory/TProtocolFactory.php b/lib/php/lib/Thrift/Factory/TProtocolFactory.php
new file mode 100644
index 0000000..6b322eb
--- /dev/null
+++ b/lib/php/lib/Thrift/Factory/TProtocolFactory.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Factory;
+
+/**
+ * Protocol factory creates protocol objects from transports
+ */
+interface TProtocolFactory {
+  /**
+   * Build a protocol from the base transport
+   *
+   * @return Thrift\Protocol\TProtocol protocol
+   */
+  public function getProtocol($trans);
+}
diff --git a/lib/php/lib/Thrift/Factory/TStringFuncFactory.php b/lib/php/lib/Thrift/Factory/TStringFuncFactory.php
new file mode 100644
index 0000000..edc3649
--- /dev/null
+++ b/lib/php/lib/Thrift/Factory/TStringFuncFactory.php
@@ -0,0 +1,63 @@
+<?php
+/*
+ * 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.
+ *
+ */
+
+namespace Thrift\Factory;
+
+use Thrift\StringFunc\Mbstring;
+use Thrift\StringFunc\Core;
+
+class TStringFuncFactory {
+    private static $_instance;
+
+    /**
+     * Get the Singleton instance of TStringFunc implementation that is
+     * compatible with the current system's mbstring.func_overload settings.
+     *
+     * @return TStringFunc
+     */
+    public static function create() {
+        if(!self::$_instance) {
+            self::_setInstance();
+        }
+
+        return self::$_instance;
+    }
+
+    private static function _setInstance() {
+        /**
+         * Cannot use str* functions for byte counting because multibyte
+         * characters will be read a single bytes.
+         *
+         * See: http://us.php.net/manual/en/mbstring.overload.php
+         */
+        if(ini_get('mbstring.func_overload') & 2) {
+            self::$_instance = new Mbstring();
+        }
+        /**
+         * mbstring is not installed or does not have function overloading
+         * of the str* functions enabled so use PHP core str* functions for
+         * byte counting.
+         */
+        else {
+            self::$_instance = new Core();
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Factory/TTransportFactory.php b/lib/php/lib/Thrift/Factory/TTransportFactory.php
new file mode 100644
index 0000000..f3ae123
--- /dev/null
+++ b/lib/php/lib/Thrift/Factory/TTransportFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Thrift\Factory;
+
+use Thrift\Transport\TTransport;
+
+class TTransportFactory {
+  /**
+   * @static
+   * @param TTransport $transport
+   * @return TTransport
+   */
+  public static function getTransport(TTransport $transport) {
+    return $transport;
+  }
+}
diff --git a/lib/php/lib/Thrift/Protocol/JSON/BaseContext.php b/lib/php/lib/Thrift/Protocol/JSON/BaseContext.php
new file mode 100644
index 0000000..e96e504
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/JSON/BaseContext.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol\JSON;
+
+class BaseContext
+{
+    function escapeNum()
+    {
+        return false;
+    }
+
+    function write()
+    {
+    }
+
+    function read()
+    {
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Protocol/JSON/ListContext.php b/lib/php/lib/Thrift/Protocol/JSON/ListContext.php
new file mode 100644
index 0000000..a2b75b1
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/JSON/ListContext.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol\JSON;
+
+use Thrift\Protocol\JSON\BaseContext;
+use Thrift\Protocol\TJSONProtocol;
+
+class ListContext extends BaseContext
+{
+    private $first_ = true;
+    private $p_;
+
+    public function __construct($p) {
+        $this->p_ = $p;
+    }
+
+    public function write() {
+        if ($this->first_) {
+            $this->first_ = false;
+        } else {
+            $this->p_->getTransport()->write(TJSONProtocol::COMMA);
+        }
+    }
+
+    public function read() {
+        if ($this->first_) {
+            $this->first_ = false;
+        } else {
+            $this->p_->readJSONSyntaxChar(TJSONProtocol::COMMA);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Protocol/JSON/LookaheadReader.php b/lib/php/lib/Thrift/Protocol/JSON/LookaheadReader.php
new file mode 100644
index 0000000..128b5fc
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/JSON/LookaheadReader.php
@@ -0,0 +1,54 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol\JSON;
+
+class LookaheadReader
+{
+    private $hasData_ = false;
+    private $data_ = array();
+    private $p_;
+
+    public function __construct($p)
+    {
+        $this->p_ = $p;
+    }
+
+    public function read() {
+        if ($this->hasData_) {
+            $this->hasData_ = false;
+        } else {
+            $this->data_ = $this->p_->getTransport()->readAll(1);
+        }
+
+        return substr($this->data_, 0, 1);
+    }
+
+    public function peek() {
+        if (!$this->hasData_) {
+            $this->data_ = $this->p_->getTransport()->readAll(1);
+        }
+
+        $this->hasData_ = true;
+        return substr($this->data_, 0, 1);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Protocol/JSON/PairContext.php b/lib/php/lib/Thrift/Protocol/JSON/PairContext.php
new file mode 100644
index 0000000..1c87dd3
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/JSON/PairContext.php
@@ -0,0 +1,60 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol\JSON;
+
+use Thrift\Protocol\JSON\BaseContext;
+use Thrift\Protocol\TJSONProtocol;
+
+class PairContext extends BaseContext {
+    private $first_ = true;
+    private $colon_ = true;
+    private $p_ = null;
+
+    public function __construct($p) {
+        $this->p_ = $p;
+    }
+
+    public function write() {
+        if ($this->first_) {
+            $this->first_ = false;
+            $this->colon_ = true;
+        } else {
+            $this->p_->getTransport()->write($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA);
+            $this->colon_ = !$this->colon_;
+        }
+    }
+
+    public function read() {
+        if ($this->first_) {
+            $this->first_ = false;
+            $this->colon_ = true;
+        } else {
+            $this->p_->readJSONSyntaxChar($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA);
+            $this->colon_ = !$this->colon_;
+        }
+    }
+
+    public function escapeNum() {
+        return $this->colon_;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Protocol/TBinaryProtocol.php b/lib/php/lib/Thrift/Protocol/TBinaryProtocol.php
new file mode 100644
index 0000000..b1fddac
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/TBinaryProtocol.php
@@ -0,0 +1,396 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol;
+
+use Thrift\Protocol\TProtocol;
+use Thrift\Type\TType;
+use Thrift\Exception\TProtocolException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Binary implementation of the Thrift protocol.
+ *
+ */
+class TBinaryProtocol extends TProtocol {
+
+  const VERSION_MASK = 0xffff0000;
+  const VERSION_1 = 0x80010000;
+
+  protected $strictRead_ = false;
+  protected $strictWrite_ = true;
+
+  public function __construct($trans, $strictRead=false, $strictWrite=true) {
+    parent::__construct($trans);
+    $this->strictRead_ = $strictRead;
+    $this->strictWrite_ = $strictWrite;
+  }
+
+  public function writeMessageBegin($name, $type, $seqid) {
+    if ($this->strictWrite_) {
+      $version = self::VERSION_1 | $type;
+      return
+        $this->writeI32($version) +
+        $this->writeString($name) +
+        $this->writeI32($seqid);
+    } else {
+      return
+        $this->writeString($name) +
+        $this->writeByte($type) +
+        $this->writeI32($seqid);
+    }
+  }
+
+  public function writeMessageEnd() {
+    return 0;
+  }
+
+  public function writeStructBegin($name) {
+    return 0;
+  }
+
+  public function writeStructEnd() {
+    return 0;
+  }
+
+  public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
+    return
+      $this->writeByte($fieldType) +
+      $this->writeI16($fieldId);
+  }
+
+  public function writeFieldEnd() {
+    return 0;
+  }
+
+  public function writeFieldStop() {
+    return
+      $this->writeByte(TType::STOP);
+  }
+
+  public function writeMapBegin($keyType, $valType, $size) {
+    return
+      $this->writeByte($keyType) +
+      $this->writeByte($valType) +
+      $this->writeI32($size);
+  }
+
+  public function writeMapEnd() {
+    return 0;
+  }
+
+  public function writeListBegin($elemType, $size) {
+    return
+      $this->writeByte($elemType) +
+      $this->writeI32($size);
+  }
+
+  public function writeListEnd() {
+    return 0;
+  }
+
+  public function writeSetBegin($elemType, $size) {
+    return
+      $this->writeByte($elemType) +
+      $this->writeI32($size);
+  }
+
+  public function writeSetEnd() {
+    return 0;
+  }
+
+  public function writeBool($value) {
+    $data = pack('c', $value ? 1 : 0);
+    $this->trans_->write($data, 1);
+    return 1;
+  }
+
+  public function writeByte($value) {
+    $data = pack('c', $value);
+    $this->trans_->write($data, 1);
+    return 1;
+  }
+
+  public function writeI16($value) {
+    $data = pack('n', $value);
+    $this->trans_->write($data, 2);
+    return 2;
+  }
+
+  public function writeI32($value) {
+    $data = pack('N', $value);
+    $this->trans_->write($data, 4);
+    return 4;
+  }
+
+  public function writeI64($value) {
+    // If we are on a 32bit architecture we have to explicitly deal with
+    // 64-bit twos-complement arithmetic since PHP wants to treat all ints
+    // as signed and any int over 2^31 - 1 as a float
+    if (PHP_INT_SIZE == 4) {
+      $neg = $value < 0;
+
+      if ($neg) {
+        $value *= -1;
+      }
+
+      $hi = (int)($value / 4294967296);
+      $lo = (int)$value;
+
+      if ($neg) {
+        $hi = ~$hi;
+        $lo = ~$lo;
+        if (($lo & (int)0xffffffff) == (int)0xffffffff) {
+          $lo = 0;
+          $hi++;
+        } else {
+          $lo++;
+        }
+      }
+      $data = pack('N2', $hi, $lo);
+
+    } else {
+      $hi = $value >> 32;
+      $lo = $value & 0xFFFFFFFF;
+      $data = pack('N2', $hi, $lo);
+    }
+
+    $this->trans_->write($data, 8);
+    return 8;
+  }
+
+  public function writeDouble($value) {
+    $data = pack('d', $value);
+    $this->trans_->write(strrev($data), 8);
+    return 8;
+  }
+
+  public function writeString($value) {
+    $len = TStringFuncFactory::create()->strlen($value);
+    $result = $this->writeI32($len);
+    if ($len) {
+      $this->trans_->write($value, $len);
+    }
+    return $result + $len;
+  }
+
+  public function readMessageBegin(&$name, &$type, &$seqid) {
+    $result = $this->readI32($sz);
+    if ($sz < 0) {
+      $version = (int) ($sz & self::VERSION_MASK);
+      if ($version != (int) self::VERSION_1) {
+        throw new TProtocolException('Bad version identifier: '.$sz, TProtocolException::BAD_VERSION);
+      }
+      $type = $sz & 0x000000ff;
+      $result +=
+        $this->readString($name) +
+        $this->readI32($seqid);
+    } else {
+      if ($this->strictRead_) {
+        throw new TProtocolException('No version identifier, old protocol client?', TProtocolException::BAD_VERSION);
+      } else {
+        // Handle pre-versioned input
+        $name = $this->trans_->readAll($sz);
+        $result +=
+          $sz +
+          $this->readByte($type) +
+          $this->readI32($seqid);
+      }
+    }
+    return $result;
+  }
+
+  public function readMessageEnd() {
+    return 0;
+  }
+
+  public function readStructBegin(&$name) {
+    $name = '';
+    return 0;
+  }
+
+  public function readStructEnd() {
+    return 0;
+  }
+
+  public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
+    $result = $this->readByte($fieldType);
+    if ($fieldType == TType::STOP) {
+      $fieldId = 0;
+      return $result;
+    }
+    $result += $this->readI16($fieldId);
+    return $result;
+  }
+
+  public function readFieldEnd() {
+    return 0;
+  }
+
+  public function readMapBegin(&$keyType, &$valType, &$size) {
+    return
+      $this->readByte($keyType) +
+      $this->readByte($valType) +
+      $this->readI32($size);
+  }
+
+  public function readMapEnd() {
+    return 0;
+  }
+
+  public function readListBegin(&$elemType, &$size) {
+    return
+      $this->readByte($elemType) +
+      $this->readI32($size);
+  }
+
+  public function readListEnd() {
+    return 0;
+  }
+
+  public function readSetBegin(&$elemType, &$size) {
+    return
+      $this->readByte($elemType) +
+      $this->readI32($size);
+  }
+
+  public function readSetEnd() {
+    return 0;
+  }
+
+  public function readBool(&$value) {
+    $data = $this->trans_->readAll(1);
+    $arr = unpack('c', $data);
+    $value = $arr[1] == 1;
+    return 1;
+  }
+
+  public function readByte(&$value) {
+    $data = $this->trans_->readAll(1);
+    $arr = unpack('c', $data);
+    $value = $arr[1];
+    return 1;
+  }
+
+  public function readI16(&$value) {
+    $data = $this->trans_->readAll(2);
+    $arr = unpack('n', $data);
+    $value = $arr[1];
+    if ($value > 0x7fff) {
+      $value = 0 - (($value - 1) ^ 0xffff);
+    }
+    return 2;
+  }
+
+  public function readI32(&$value) {
+    $data = $this->trans_->readAll(4);
+    $arr = unpack('N', $data);
+    $value = $arr[1];
+    if ($value > 0x7fffffff) {
+      $value = 0 - (($value - 1) ^ 0xffffffff);
+    }
+    return 4;
+  }
+
+  public function readI64(&$value) {
+    $data = $this->trans_->readAll(8);
+
+    $arr = unpack('N2', $data);
+
+    // If we are on a 32bit architecture we have to explicitly deal with
+    // 64-bit twos-complement arithmetic since PHP wants to treat all ints
+    // as signed and any int over 2^31 - 1 as a float
+    if (PHP_INT_SIZE == 4) {
+
+      $hi = $arr[1];
+      $lo = $arr[2];
+      $isNeg = $hi  < 0;
+
+      // Check for a negative
+      if ($isNeg) {
+        $hi = ~$hi & (int)0xffffffff;
+        $lo = ~$lo & (int)0xffffffff;
+
+        if ($lo == (int)0xffffffff) {
+          $hi++;
+          $lo = 0;
+        } else {
+          $lo++;
+        }
+      }
+
+      // Force 32bit words in excess of 2G to pe positive - we deal wigh sign
+      // explicitly below
+
+      if ($hi & (int)0x80000000) {
+        $hi &= (int)0x7fffffff;
+        $hi += 0x80000000;
+      }
+
+      if ($lo & (int)0x80000000) {
+        $lo &= (int)0x7fffffff;
+        $lo += 0x80000000;
+      }
+
+      $value = $hi * 4294967296 + $lo;
+
+      if ($isNeg) {
+        $value = 0 - $value;
+      }
+    } else {
+
+      // Upcast negatives in LSB bit
+      if ($arr[2] & 0x80000000) {
+        $arr[2] = $arr[2] & 0xffffffff;
+      }
+
+      // Check for a negative
+      if ($arr[1] & 0x80000000) {
+        $arr[1] = $arr[1] & 0xffffffff;
+        $arr[1] = $arr[1] ^ 0xffffffff;
+        $arr[2] = $arr[2] ^ 0xffffffff;
+        $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
+      } else {
+        $value = $arr[1]*4294967296 + $arr[2];
+      }
+    }
+
+    return 8;
+  }
+
+  public function readDouble(&$value) {
+    $data = strrev($this->trans_->readAll(8));
+    $arr = unpack('d', $data);
+    $value = $arr[1];
+    return 8;
+  }
+
+  public function readString(&$value) {
+    $result = $this->readI32($len);
+    if ($len) {
+      $value = $this->trans_->readAll($len);
+    } else {
+      $value = '';
+    }
+    return $result + $len;
+  }
+}
diff --git a/lib/php/lib/Thrift/Protocol/TBinaryProtocolAccelerated.php b/lib/php/lib/Thrift/Protocol/TBinaryProtocolAccelerated.php
new file mode 100644
index 0000000..392aa21
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/TBinaryProtocolAccelerated.php
@@ -0,0 +1,47 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol;
+
+use Thrift\Protocol\TBinaryProtocol;
+use Thrift\Transport\TBufferedTransport;
+
+/**
+ * Accelerated binary protocol: used in conjunction with the thrift_protocol
+ * extension for faster deserialization
+ */
+class TBinaryProtocolAccelerated extends TBinaryProtocol {
+  public function __construct($trans, $strictRead=false, $strictWrite=true) {
+    // If the transport doesn't implement putBack, wrap it in a
+    // TBufferedTransport (which does)
+    if (!method_exists($trans, 'putBack')) {
+      $trans = new TBufferedTransport($trans);
+    }
+    parent::__construct($trans, $strictRead, $strictWrite);
+  }
+  public function isStrictRead() {
+    return $this->strictRead_;
+  }
+  public function isStrictWrite() {
+    return $this->strictWrite_;
+  }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Protocol/TCompactProtocol.php b/lib/php/lib/Thrift/Protocol/TCompactProtocol.php
new file mode 100644
index 0000000..e637a59
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/TCompactProtocol.php
@@ -0,0 +1,669 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol;
+
+use Thrift\Protocol\TProtocol;
+use Thrift\Type\TType;
+use Thrift\Exception\TProtocolException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Compact implementation of the Thrift protocol.
+ *
+ */
+class TCompactProtocol extends TProtocol {
+
+  const COMPACT_STOP = 0x00;
+  const COMPACT_TRUE = 0x01;
+  const COMPACT_FALSE = 0x02;
+  const COMPACT_BYTE = 0x03;
+  const COMPACT_I16 = 0x04;
+  const COMPACT_I32 = 0x05;
+  const COMPACT_I64 = 0x06;
+  const COMPACT_DOUBLE = 0x07;
+  const COMPACT_BINARY = 0x08;
+  const COMPACT_LIST = 0x09;
+  const COMPACT_SET = 0x0A;
+  const COMPACT_MAP = 0x0B;
+  const COMPACT_STRUCT = 0x0C;
+
+  const STATE_CLEAR = 0;
+  const STATE_FIELD_WRITE = 1;
+  const STATE_VALUE_WRITE = 2;
+  const STATE_CONTAINER_WRITE = 3;
+  const STATE_BOOL_WRITE = 4;
+  const STATE_FIELD_READ = 5;
+  const STATE_CONTAINER_READ = 6;
+  const STATE_VALUE_READ = 7;
+  const STATE_BOOL_READ = 8;
+
+  const VERSION_MASK = 0x1f;
+  const VERSION = 1;
+  const PROTOCOL_ID = 0x82;
+  const TYPE_MASK = 0xe0;
+  const TYPE_SHIFT_AMOUNT = 5;
+
+  protected static $ctypes = array(
+    TType::STOP => TCompactProtocol::COMPACT_STOP,
+    TType::BOOL => TCompactProtocol::COMPACT_TRUE, // used for collection
+    TType::BYTE => TCompactProtocol::COMPACT_BYTE,
+    TType::I16 => TCompactProtocol::COMPACT_I16,
+    TType::I32 => TCompactProtocol::COMPACT_I32,
+    TType::I64 => TCompactProtocol::COMPACT_I64,
+    TType::DOUBLE => TCompactProtocol::COMPACT_DOUBLE,
+    TType::STRING => TCompactProtocol::COMPACT_BINARY,
+    TType::STRUCT => TCompactProtocol::COMPACT_STRUCT,
+    TType::LST => TCompactProtocol::COMPACT_LIST,
+    TType::SET => TCompactProtocol::COMPACT_SET,
+    TType::MAP => TCompactProtocol::COMPACT_MAP,
+  );
+
+  protected static $ttypes = array(
+    TCompactProtocol::COMPACT_STOP => TType::STOP ,
+    TCompactProtocol::COMPACT_TRUE => TType::BOOL, // used for collection
+    TCompactProtocol::COMPACT_FALSE => TType::BOOL,
+    TCompactProtocol::COMPACT_BYTE => TType::BYTE,
+    TCompactProtocol::COMPACT_I16 => TType::I16,
+    TCompactProtocol::COMPACT_I32 => TType::I32,
+    TCompactProtocol::COMPACT_I64 => TType::I64,
+    TCompactProtocol::COMPACT_DOUBLE => TType::DOUBLE,
+    TCompactProtocol::COMPACT_BINARY => TType::STRING,
+    TCompactProtocol::COMPACT_STRUCT => TType::STRUCT,
+    TCompactProtocol::COMPACT_LIST => TType::LST,
+    TCompactProtocol::COMPACT_SET => TType::SET,
+    TCompactProtocol::COMPACT_MAP => TType::MAP,
+  );
+
+  protected $state = TCompactProtocol::STATE_CLEAR;
+  protected $lastFid = 0;
+  protected $boolFid = null;
+  protected $boolValue = null;
+  protected $structs = array();
+  protected $containers = array();
+
+  // Some varint / zigzag helper methods
+  public function toZigZag($n, $bits) {
+    return ($n << 1) ^ ($n >> ($bits - 1));
+  }
+
+  public function fromZigZag($n) {
+    return ($n >> 1) ^ -($n & 1);
+  }
+
+  public function getVarint($data) {
+    $out = "";
+    while (true) {
+      if (($data & ~0x7f) === 0) {
+        $out .= chr($data);
+        break;
+      } else {
+        $out .= chr(($data & 0xff) | 0x80);
+        $data = $data >> 7;
+      }
+    }
+    return $out;
+  }
+
+  public function writeVarint($data) {
+    $out = $this->getVarint($data);
+    $result = TStringFuncFactory::create()->strlen($out);
+    $this->trans_->write($out, $result);
+    return $result;
+  }
+
+  public function readVarint(&$result) {
+    $idx = 0;
+    $shift = 0;
+    $result = 0;
+    while (true) {
+      $x = $this->trans_->readAll(1);
+      $arr = unpack('C', $x);
+      $byte = $arr[1];
+      $idx += 1;
+      $result |= ($byte & 0x7f) << $shift;
+      if (($byte >> 7) === 0) {
+        return $idx;
+      }
+      $shift += 7;
+    }
+
+    return $idx;
+  }
+
+  public function __construct($trans) {
+    parent::__construct($trans);
+  }
+
+  public function writeMessageBegin($name, $type, $seqid) {
+    $written =
+      $this->writeUByte(TCompactProtocol::PROTOCOL_ID) +
+      $this->writeUByte(TCompactProtocol::VERSION |
+                        ($type << TCompactProtocol::TYPE_SHIFT_AMOUNT)) +
+      $this->writeVarint($seqid) +
+      $this->writeString($name);
+    $this->state = TCompactProtocol::STATE_VALUE_WRITE;
+    return $written;
+  }
+
+  public function writeMessageEnd() {
+    $this->state = TCompactProtocol::STATE_CLEAR;
+    return 0;
+  }
+
+  public function writeStructBegin($name) {
+    $this->structs[] = array($this->state, $this->lastFid);
+    $this->state = TCompactProtocol::STATE_FIELD_WRITE;
+    $this->lastFid = 0;
+    return 0;
+  }
+
+  public function writeStructEnd() {
+    $old_values = array_pop($this->structs);
+    $this->state = $old_values[0];
+    $this->lastFid = $old_values[1];
+    return 0;
+  }
+
+  public function writeFieldStop() {
+    return $this->writeByte(0);
+  }
+
+  public function writeFieldHeader($type, $fid) {
+    $written = 0;
+    $delta = $fid - $this->lastFid;
+    if (0 < $delta && $delta <= 15) {
+      $written = $this->writeUByte(($delta << 4) | $type);
+    } else {
+      $written = $this->writeByte($type) +
+        $this->writeI16($fid);
+    }
+    $this->lastFid = $fid;
+    return $written;
+  }
+
+  public function writeFieldBegin($field_name, $field_type, $field_id) {
+    if ($field_type == TTYPE::BOOL) {
+      $this->state = TCompactProtocol::STATE_BOOL_WRITE;
+      $this->boolFid = $field_id;
+      return 0;
+    } else {
+      $this->state = TCompactProtocol::STATE_VALUE_WRITE;
+      return $this->writeFieldHeader(self::$ctypes[$field_type], $field_id);
+    }
+  }
+
+  public function writeFieldEnd() {
+    $this->state = TCompactProtocol::STATE_FIELD_WRITE;
+    return 0;
+  }
+
+  public function writeCollectionBegin($etype, $size) {
+    $written = 0;
+    if ($size <= 14) {
+      $written = $this->writeUByte($size << 4 |
+                                    self::$ctypes[$etype]);
+    } else {
+      $written = $this->writeUByte(0xf0 |
+                                   self::$ctypes[$etype]) +
+        $this->writeVarint($size);
+    }
+    $this->containers[] = $this->state;
+    $this->state = TCompactProtocol::STATE_CONTAINER_WRITE;
+
+    return $written;
+  }
+
+  public function writeMapBegin($key_type, $val_type, $size) {
+    $written = 0;
+    if ($size == 0) {
+      $written = $this->writeByte(0);
+    } else {
+      $written = $this->writeVarint($size) +
+        $this->writeUByte(self::$ctypes[$key_type] << 4 |
+                          self::$ctypes[$val_type]);
+    }
+    $this->containers[] = $this->state;
+    return $written;
+  }
+
+  public function writeCollectionEnd() {
+    $this->state = array_pop($this->containers);
+    return 0;
+  }
+
+  public function writeMapEnd() {
+    return $this->writeCollectionEnd();
+  }
+
+  public function writeListBegin($elem_type, $size) {
+    return $this->writeCollectionBegin($elem_type, $size);
+  }
+
+  public function writeListEnd() {
+    return $this->writeCollectionEnd();
+  }
+
+  public function writeSetBegin($elem_type, $size) {
+    return $this->writeCollectionBegin($elem_type, $size);
+  }
+
+  public function writeSetEnd() {
+    return $this->writeCollectionEnd();
+  }
+
+  public function writeBool($value) {
+    if ($this->state == TCompactProtocol::STATE_BOOL_WRITE) {
+      $ctype = TCompactProtocol::COMPACT_FALSE;
+      if ($value) {
+        $ctype = TCompactProtocol::COMPACT_TRUE;
+      }
+      return $this->writeFieldHeader($ctype, $this->boolFid);
+    } else if ($this->state == TCompactProtocol::STATE_CONTAINER_WRITE) {
+      return $this->writeByte($value ? 1 : 0);
+    } else {
+      throw new TProtocolException('Invalid state in compact protocol');
+    }
+  }
+
+  public function writeByte($value) {
+    $data = pack('c', $value);
+    $this->trans_->write($data, 1);
+    return 1;
+  }
+
+  public function writeUByte($byte) {
+    $this->trans_->write(pack('C', $byte), 1);
+    return 1;
+  }
+
+  public function writeI16($value) {
+    $thing = $this->toZigZag($value, 16);
+    return $this->writeVarint($thing);
+  }
+
+  public function writeI32($value) {
+    $thing = $this->toZigZag($value, 32);
+    return $this->writeVarint($thing);
+  }
+
+  public function writeDouble($value) {
+    $data = pack('d', $value);
+    $this->trans_->write(strrev($data), 8);
+    return 8;
+  }
+
+  public function writeString($value) {
+    $len = TStringFuncFactory::create()->strlen($value);
+    $result = $this->writeVarint($len);
+    if ($len) {
+      $this->trans_->write($value, $len);
+    }
+    return $result + $len;
+  }
+
+  public function readFieldBegin(&$name, &$field_type, &$field_id) {
+    $result = $this->readUByte($field_type);
+
+    if (($field_type & 0x0f) == TType::STOP) {
+      $field_id = 0;
+      return $result;
+    }
+    $delta = $field_type >> 4;
+    if ($delta == 0) {
+      $result += $this->readI16($field_id);
+    } else {
+      $field_id = $this->lastFid + $delta;
+    }
+    $this->lastFid = $field_id;
+    $field_type = $this->getTType($field_type & 0x0f);
+    if ($field_type == TCompactProtocol::COMPACT_TRUE) {
+      $this->state = TCompactProtocol::STATE_BOOL_READ;
+      $this->boolValue = true;
+    } else if ($field_type == TCompactProtocol::COMPACT_FALSE) {
+      $this->state = TCompactProtocol::STATE_BOOL_READ;
+      $this->boolValue = false;
+    } else {
+      $this->state = TCompactProtocol::STATE_VALUE_READ;
+    }
+    return $result;
+  }
+
+  public function readFieldEnd() {
+    $this->state = TCompactProtocol::STATE_FIELD_READ;
+    return 0;
+  }
+
+  public function readUByte(&$value) {
+    $data = $this->trans_->readAll(1);
+    $arr = unpack('C', $data);
+    $value = $arr[1];
+    return 1;
+  }
+
+  public function readByte(&$value) {
+    $data = $this->trans_->readAll(1);
+    $arr = unpack('c', $data);
+    $value = $arr[1];
+    return 1;
+  }
+
+  public function readZigZag(&$value) {
+    $result = $this->readVarint($value);
+    $value = $this->fromZigZag($value);
+    return $result;
+  }
+
+  public function readMessageBegin(&$name, &$type, &$seqid) {
+    $protoId = 0;
+    $result = $this->readUByte($protoId);
+    if ($protoId != TCompactProtocol::PROTOCOL_ID) {
+      throw new TProtocolException('Bad protocol id in TCompact message');
+    }
+    $verType = 0;
+    $result += $this->readUByte($verType);
+    $type = ($verType & TCompactProtocol::TYPE_MASK) >>
+      TCompactProtocol::TYPE_SHIFT_AMOUNT;
+    $version = $verType & TCompactProtocol::VERSION_MASK;
+    if ($version != TCompactProtocol::VERSION) {
+      throw new TProtocolException('Bad version in TCompact message');
+    }
+    $result += $this->readVarint($seqId);
+    $name += $this->readString($name);
+
+    return $result;
+  }
+
+  public function readMessageEnd() {
+    return 0;
+  }
+
+  public function readStructBegin(&$name) {
+    $name = ''; // unused
+    $this->structs[] = array($this->state, $this->lastFid);
+    $this->state = TCompactProtocol::STATE_FIELD_READ;
+    $this->lastFid = 0;
+    return 0;
+  }
+
+  public function readStructEnd() {
+    $last = array_pop($this->structs);
+    $this->state = $last[0];
+    $this->lastFid = $last[1];
+    return 0;
+  }
+
+  public function readCollectionBegin(&$type, &$size) {
+    $sizeType = 0;
+    $result = $this->readUByte($sizeType);
+    $size = $sizeType >> 4;
+    $type = $this->getTType($sizeType);
+    if ($size == 15) {
+      $result += $this->readVarint($size);
+    }
+    $this->containers[] = $this->state;
+    $this->state = TCompactProtocol::STATE_CONTAINER_READ;
+
+    return $result;
+  }
+
+  public function readMapBegin(&$key_type, &$val_type, &$size) {
+    $result = $this->readVarint($size);
+    $types = 0;
+    if ($size > 0) {
+      $result += $this->readUByte($types);
+    }
+    $val_type = $this->getTType($types);
+    $key_type = $this->getTType($types >> 4);
+    $this->containers[] = $this->state;
+    $this->state = TCompactProtocol::STATE_CONTAINER_READ;
+
+    return $result;
+  }
+
+  public function readCollectionEnd() {
+    $this->state = array_pop($this->containers);
+    return 0;
+  }
+
+  public function readMapEnd() {
+    return $this->readCollectionEnd();
+  }
+
+  public function readListBegin(&$elem_type, &$size) {
+    return $this->readCollectionBegin($elem_type, $size);
+  }
+
+  public function readListEnd() {
+    return $this->readCollectionEnd();
+  }
+
+  public function readSetBegin(&$elem_type, &$size) {
+    return $this->readCollectionBegin($elem_type, $size);
+  }
+
+  public function readSetEnd() {
+    return $this->readCollectionEnd();
+  }
+
+  public function readBool(&$value) {
+    if ($this->state == TCompactProtocol::STATE_BOOL_READ) {
+      $value = $this->boolValue;
+      return 0;
+    } else if ($this->state == TCompactProtocol::STATE_CONTAINER_READ) {
+      return $this->readByte($value);
+    } else {
+      throw new TProtocolException('Invalid state in compact protocol');
+    }
+  }
+
+  public function readI16(&$value) {
+    return $this->readZigZag($value);
+  }
+
+  public function readI32(&$value) {
+    return $this->readZigZag($value);
+  }
+
+  public function readDouble(&$value) {
+    $data = strrev($this->trans_->readAll(8));
+    $arr = unpack('d', $data);
+    $value = $arr[1];
+    return 8;
+  }
+
+  public function readString(&$value) {
+    $result = $this->readVarint($len);
+    if ($len) {
+      $value = $this->trans_->readAll($len);
+    } else {
+      $value = '';
+    }
+    return $result + $len;
+  }
+
+  public function getTType($byte) {
+    return self::$ttypes[$byte & 0x0f];
+  }
+
+  // If we are on a 32bit architecture we have to explicitly deal with
+  // 64-bit twos-complement arithmetic since PHP wants to treat all ints
+  // as signed and any int over 2^31 - 1 as a float
+
+  // Read and write I64 as two 32 bit numbers $hi and $lo
+
+  public function readI64(&$value) {
+    // Read varint from wire
+    $hi = 0;
+    $lo = 0;
+
+    $idx = 0;
+    $shift = 0;
+
+    while (true) {
+      $x = $this->trans_->readAll(1);
+      $arr = unpack('C', $x);
+      $byte = $arr[1];
+      $idx += 1;
+      if ($shift < 32) {
+        $lo |= (($byte & 0x7f) << $shift) &
+          0x00000000ffffffff;
+      }
+      // Shift hi and lo together.
+      if ($shift >= 32) {
+        $hi |= (($byte & 0x7f) << ($shift - 32));
+      } else if ($shift > 25) {
+        $hi |= (($byte & 0x7f) >> ($shift - 25));
+      }
+      if (($byte >> 7) === 0) {
+        break;
+      }
+      $shift += 7;
+    }
+
+    // Now, unzig it.
+    $xorer = 0;
+    if ($lo & 1) {
+      $xorer = 0xffffffff;
+    }
+    $lo = ($lo >> 1) & 0x7fffffff;
+    $lo = $lo | (($hi & 1) << 31);
+    $hi = ($hi >> 1) ^ $xorer;
+    $lo = $lo ^ $xorer;
+
+    // Now put $hi and $lo back together
+    if (true) {
+      $isNeg = $hi  < 0;
+
+      // Check for a negative
+      if ($isNeg) {
+        $hi = ~$hi & (int)0xffffffff;
+        $lo = ~$lo & (int)0xffffffff;
+
+        if ($lo == (int)0xffffffff) {
+          $hi++;
+          $lo = 0;
+        } else {
+          $lo++;
+        }
+      }
+
+      // Force 32bit words in excess of 2G to be positive - we deal with sign
+      // explicitly below
+
+      if ($hi & (int)0x80000000) {
+        $hi &= (int)0x7fffffff;
+        $hi += 0x80000000;
+      }
+
+      if ($lo & (int)0x80000000) {
+        $lo &= (int)0x7fffffff;
+        $lo += 0x80000000;
+      }
+
+      $value = $hi * 4294967296 + $lo;
+
+      if ($isNeg) {
+        $value = 0 - $value;
+      }
+    } else {
+
+      // Upcast negatives in LSB bit
+      if ($arr[2] & 0x80000000) {
+        $arr[2] = $arr[2] & 0xffffffff;
+      }
+
+      // Check for a negative
+      if ($arr[1] & 0x80000000) {
+        $arr[1] = $arr[1] & 0xffffffff;
+        $arr[1] = $arr[1] ^ 0xffffffff;
+        $arr[2] = $arr[2] ^ 0xffffffff;
+        $value = 0 - $arr[1] * 4294967296 - $arr[2] - 1;
+      } else {
+        $value = $arr[1] * 4294967296 + $arr[2];
+      }
+    }
+
+    return $idx;
+  }
+
+  public function writeI64($value) {
+    // If we are in an I32 range, use the easy method below.
+    if (($value > 4294967296) || ($value < -4294967296)) {
+      // Convert $value to $hi and $lo
+      $neg = $value < 0;
+
+      if ($neg) {
+        $value *= -1;
+      }
+
+      $hi = (int)$value >> 32;
+      $lo = (int)$value & 0xffffffff;
+
+      if ($neg) {
+        $hi = ~$hi;
+        $lo = ~$lo;
+        if (($lo & (int)0xffffffff) == (int)0xffffffff) {
+          $lo = 0;
+          $hi++;
+        } else {
+          $lo++;
+        }
+      }
+
+      // Now do the zigging and zagging.
+      $xorer = 0;
+      if ($neg) {
+        $xorer = 0xffffffff;
+      }
+      $lowbit = ($lo >> 31) & 1;
+      $hi = ($hi << 1) | $lowbit;
+      $lo = ($lo << 1);
+      $lo = ($lo ^ $xorer) & 0xffffffff;
+      $hi = ($hi ^ $xorer) & 0xffffffff;
+
+      // now write out the varint, ensuring we shift both hi and lo
+      $out = "";
+      while (true) {
+        if (($lo & ~0x7f) === 0 &&
+           $hi === 0) {
+          $out .= chr($lo);
+          break;
+        } else {
+          $out .= chr(($lo & 0xff) | 0x80);
+          $lo = $lo >> 7;
+          $lo = $lo | ($hi << 25);
+          $hi = $hi >> 7;
+          // Right shift carries sign, but we don't want it to.
+          $hi = $hi & (127 << 25);
+        }
+      }
+
+      $ret = TStringFuncFactory::create()->strlen($out);
+      $this->trans_->write($out, $ret);
+
+      return $ret;
+    } else {
+      return $this->writeVarint($this->toZigZag($value, 64));
+    }
+  }
+}
diff --git a/lib/php/lib/Thrift/Protocol/TJSONProtocol.php b/lib/php/lib/Thrift/Protocol/TJSONProtocol.php
new file mode 100644
index 0000000..3d39583
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/TJSONProtocol.php
@@ -0,0 +1,694 @@
+<?php
+
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol;
+
+use Thrift\Protocol\TProtocol;
+use Thrift\Type\TType;
+use Thrift\Exception\TProtocolException;
+use Thrift\Protocol\JSON\BaseContext;
+use Thrift\Protocol\JSON\LookaheadReader;
+use Thrift\Protocol\JSON\PairContext;
+use Thrift\Protocol\JSON\ListContext;
+
+/**
+ * JSON implementation of thrift protocol, ported from Java.
+ */
+class TJSONProtocol extends TProtocol
+{
+    const COMMA = ',';
+    const COLON = ':';
+    const LBRACE = '{';
+    const RBRACE = '}';
+    const LBRACKET = '[';
+    const RBRACKET = ']';
+    const QUOTE = '"';
+    const BACKSLASH = '\\';
+    const ZERO = '0';
+    const ESCSEQ = '\\';
+    const DOUBLEESC = '__DOUBLE_ESCAPE_SEQUENCE__';
+
+    const VERSION = 1;
+
+    public static $JSON_CHAR_TABLE = array(
+        /*  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
+        0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
+        1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+    );
+
+    public static $ESCAPE_CHARS = array('"', '\\', "b", "f", "n", "r", "t");
+
+    public static $ESCAPE_CHAR_VALS = array(
+        '"', '\\', "\x08", "\f", "\n", "\r", "\t",
+    );
+
+    const NAME_BOOL = "tf";
+    const NAME_BYTE = "i8";
+    const NAME_I16 = "i16";
+    const NAME_I32 = "i32";
+    const NAME_I64 = "i64";
+    const NAME_DOUBLE = "dbl";
+    const NAME_STRUCT = "rec";
+    const NAME_STRING = "str";
+    const NAME_MAP = "map";
+    const NAME_LIST = "lst";
+    const NAME_SET = "set";
+
+    private function getTypeNameForTypeID($typeID)
+    {
+        switch ($typeID) {
+            case TType::BOOL:
+                return self::NAME_BOOL;
+            case TType::BYTE:
+                return self::NAME_BYTE;
+            case TType::I16:
+                return self::NAME_I16;
+            case TType::I32:
+                return self::NAME_I32;
+            case TType::I64:
+                return self::NAME_I64;
+            case TType::DOUBLE:
+                return self::NAME_DOUBLE;
+            case TType::STRING:
+                return self::NAME_STRING;
+            case TType::STRUCT:
+                return self::NAME_STRUCT;
+            case TType::MAP:
+                return self::NAME_MAP;
+            case TType::SET:
+                return self::NAME_SET;
+            case TType::LST:
+                return self::NAME_LIST;
+            default:
+                throw new TProtocolException("Unrecognized type", TProtocolException::UNKNOWN);
+        }
+    }
+
+    private function getTypeIDForTypeName($name)
+    {
+        $result = TType::STOP;
+
+        if (strlen($name) > 1) {
+            switch (substr($name, 0, 1)) {
+                case 'd':
+                    $result = TType::DOUBLE;
+                    break;
+                case 'i':
+                    switch (substr($name, 1, 1)) {
+                        case '8':
+                            $result = TType::BYTE;
+                            break;
+                        case '1':
+                            $result = TType::I16;
+                            break;
+                        case '3':
+                            $result = TType::I32;
+                            break;
+                        case '6':
+                            $result = TType::I64;
+                            break;
+                    }
+                    break;
+                case 'l':
+                    $result = TType::LST;
+                    break;
+                case 'm':
+                    $result = TType::MAP;
+                    break;
+                case 'r':
+                    $result = TType::STRUCT;
+                    break;
+                case 's':
+                    if (substr($name, 1, 1) == 't') {
+                        $result = TType::STRING;
+                    }
+                    else if (substr($name, 1, 1) == 'e') {
+                        $result = TType::SET;
+                    }
+                    break;
+                case 't':
+                    $result = TType::BOOL;
+                    break;
+            }
+        }
+        if ($result == TType::STOP) {
+            throw new TProtocolException("Unrecognized type", TProtocolException::INVALID_DATA);
+        }
+        return $result;
+    }
+
+    public $contextStack_ = array();
+    public $context_;
+    public $reader_;
+
+    private function pushContext($c) {
+        array_push($this->contextStack_, $this->context_);
+        $this->context_ = $c;
+    }
+
+    private function popContext() {
+        $this->context_ = array_pop($this->contextStack_);
+    }
+
+    public function __construct($trans) {
+        parent::__construct($trans);
+        $this->context_ = new BaseContext();
+        $this->reader_ = new LookaheadReader($this);
+    }
+
+    public function reset() {
+        $this->contextStack_ = array();
+        $this->context_ = new BaseContext();
+        $this->reader_ = new LookaheadReader($this);
+    }
+
+    private $tmpbuf_ = array(4);
+
+    public function readJSONSyntaxChar($b) {
+        $ch = $this->reader_->read();
+
+        if (substr($ch, 0, 1) != $b) {
+            throw new TProtocolException("Unexpected character: " . $ch, TProtocolException::INVALID_DATA);
+        }
+    }
+
+    private function hexVal($s) {
+        for ($i = 0; $i < strlen($s); $i++) {
+            $ch = substr($s, $i, 1);
+
+            if (!($ch >= "a" && $ch <= "f") && !($ch >= "0" && $ch <= "9")) {
+                throw new TProtocolException("Expected hex character " . $ch, TProtocolException::INVALID_DATA);
+            }
+        }
+
+        return hexdec($s);
+    }
+
+    private function hexChar($val) {
+        return dechex($val);
+    }
+
+    private function writeJSONString($b) {
+        $this->context_->write();
+
+        if (is_numeric($b) && $this->context_->escapeNum()) {
+            $this->trans_->write(self::QUOTE);
+        }
+
+        $this->trans_->write(json_encode($b));
+
+        if (is_numeric($b) && $this->context_->escapeNum()) {
+            $this->trans_->write(self::QUOTE);
+        }
+    }
+
+    private function writeJSONInteger($num) {
+        $this->context_->write();
+
+        if ($this->context_->escapeNum()) {
+            $this->trans_->write(self::QUOTE);
+        }
+
+        $this->trans_->write($num);
+
+        if ($this->context_->escapeNum()) {
+            $this->trans_->write(self::QUOTE);
+        }
+    }
+
+    private function writeJSONDouble($num) {
+        $this->context_->write();
+
+        if ($this->context_->escapeNum()) {
+            $this->trans_->write(self::QUOTE);
+        }
+
+        $this->trans_->write(json_encode($num));
+
+        if ($this->context_->escapeNum()) {
+            $this->trans_->write(self::QUOTE);
+        }
+    }
+
+    private function writeJSONBase64($data) {
+        $this->context_->write();
+        $this->trans_->write(self::QUOTE);
+        $this->trans_->write(json_encode(base64_encode($data)));
+        $this->trans_->write(self::QUOTE);
+    }
+
+    private function writeJSONObjectStart() {
+      $this->context_->write();
+      $this->trans_->write(self::LBRACE);
+      $this->pushContext(new PairContext($this));
+    }
+
+    private function writeJSONObjectEnd() {
+      $this->popContext();
+      $this->trans_->write(self::RBRACE);
+    }
+
+    private function writeJSONArrayStart() {
+      $this->context_->write();
+      $this->trans_->write(self::LBRACKET);
+      $this->pushContext(new ListContext($this));
+    }
+
+    private function writeJSONArrayEnd() {
+      $this->popContext();
+      $this->trans_->write(self::RBRACKET);
+    }
+
+    private function readJSONString($skipContext) {
+      if (!$skipContext) {
+        $this->context_->read();
+      }
+
+      $jsonString = '';
+      $lastChar = NULL;
+      while (true) {
+        $ch = $this->reader_->read();
+        $jsonString .= $ch;
+        if ($ch == self::QUOTE &&
+          $lastChar !== NULL &&
+            $lastChar !== self::ESCSEQ) {
+          break;
+        }
+        if ($ch == self::ESCSEQ && $lastChar == self::ESCSEQ) {
+          $lastChar = self::DOUBLEESC;
+        } else {
+          $lastChar = $ch;
+        }
+      }
+      return json_decode($jsonString);
+    }
+
+    private function isJSONNumeric($b) {
+        switch ($b) {
+            case '+':
+            case '-':
+            case '.':
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case 'E':
+            case 'e':
+              return true;
+            }
+        return false;
+    }
+
+    private function readJSONNumericChars() {
+        $strbld = array();
+
+        while (true) {
+            $ch = $this->reader_->peek();
+
+            if (!$this->isJSONNumeric($ch)) {
+                break;
+            }
+
+            $strbld[] = $this->reader_->read();
+        }
+
+        return implode("", $strbld);
+    }
+
+    private function readJSONInteger() {
+        $this->context_->read();
+
+        if ($this->context_->escapeNum()) {
+            $this->readJSONSyntaxChar(self::QUOTE);
+        }
+
+        $str = $this->readJSONNumericChars();
+
+        if ($this->context_->escapeNum()) {
+            $this->readJSONSyntaxChar(self::QUOTE);
+        }
+
+        if (!is_numeric($str)) {
+            throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA);
+        }
+
+        return intval($str);
+    }
+
+    /**
+     * Identical to readJSONInteger but without the final cast.
+     * Needed for proper handling of i64 on 32 bit machines.  Why a
+     * separate function?  So we don't have to force the rest of the
+     * use cases through the extra conditional.
+     */
+    private function readJSONIntegerAsString() {
+        $this->context_->read();
+
+        if ($this->context_->escapeNum()) {
+            $this->readJSONSyntaxChar(self::QUOTE);
+        }
+
+        $str = $this->readJSONNumericChars();
+
+        if ($this->context_->escapeNum()) {
+            $this->readJSONSyntaxChar(self::QUOTE);
+        }
+
+        if (!is_numeric($str)) {
+            throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA);
+        }
+
+        return $str;
+    }
+
+    private function readJSONDouble() {
+        $this->context_->read();
+
+        if (substr($this->reader_->peek(), 0, 1) == self::QUOTE) {
+            $arr = $this->readJSONString(true);
+
+            if ($arr == "NaN") {
+                return NAN;
+            } else if ($arr == "Infinity") {
+                return INF;
+            } else if (!$this->context_->escapeNum()) {
+                throw new TProtocolException("Numeric data unexpectedly quoted " . $arr,
+                                              TProtocolException::INVALID_DATA);
+            }
+
+            return floatval($arr);
+        } else {
+            if ($this->context_->escapeNum()) {
+                $this->readJSONSyntaxChar(self::QUOTE);
+            }
+
+            return floatval($this->readJSONNumericChars());
+        }
+    }
+
+    private function readJSONBase64() {
+        $arr = $this->readJSONString(false);
+        $data = base64_decode($arr, true);
+
+        if ($data === false) {
+            throw new TProtocolException("Invalid base64 data " . $arr, TProtocolException::INVALID_DATA);
+        }
+
+        return $data;
+    }
+
+    private function readJSONObjectStart() {
+        $this->context_->read();
+        $this->readJSONSyntaxChar(self::LBRACE);
+        $this->pushContext(new PairContext($this));
+    }
+
+    private function readJSONObjectEnd() {
+        $this->readJSONSyntaxChar(self::RBRACE);
+        $this->popContext();
+    }
+
+    private function readJSONArrayStart()
+    {
+        $this->context_->read();
+        $this->readJSONSyntaxChar(self::LBRACKET);
+        $this->pushContext(new ListContext($this));
+    }
+
+    private function readJSONArrayEnd() {
+        $this->readJSONSyntaxChar(self::RBRACKET);
+        $this->popContext();
+    }
+
+    /**
+     * Writes the message header
+     *
+     * @param string $name Function name
+     * @param int $type message type TMessageType::CALL or TMessageType::REPLY
+     * @param int $seqid The sequence id of this message
+     */
+    public function writeMessageBegin($name, $type, $seqid) {
+        $this->writeJSONArrayStart();
+        $this->writeJSONInteger(self::VERSION);
+        $this->writeJSONString($name);
+        $this->writeJSONInteger($type);
+        $this->writeJSONInteger($seqid);
+    }
+
+    /**
+     * Close the message
+     */
+    public function writeMessageEnd() {
+        $this->writeJSONArrayEnd();
+    }
+
+    /**
+     * Writes a struct header.
+     *
+     * @param string     $name Struct name
+     * @throws TException on write error
+     * @return int How many bytes written
+     */
+    public function writeStructBegin($name) {
+        $this->writeJSONObjectStart();
+    }
+
+    /**
+     * Close a struct.
+     *
+     * @throws TException on write error
+     * @return int How many bytes written
+     */
+    public function writeStructEnd() {
+        $this->writeJSONObjectEnd();
+    }
+
+    public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
+        $this->writeJSONInteger($fieldId);
+        $this->writeJSONObjectStart();
+        $this->writeJSONString($this->getTypeNameForTypeID($fieldType));
+    }
+
+    public function writeFieldEnd() {
+        $this->writeJsonObjectEnd();
+    }
+
+    public function writeFieldStop() {
+    }
+
+    public function writeMapBegin($keyType, $valType, $size) {
+        $this->writeJSONArrayStart();
+        $this->writeJSONString($this->getTypeNameForTypeID($keyType));
+        $this->writeJSONString($this->getTypeNameForTypeID($valType));
+        $this->writeJSONInteger($size);
+        $this->writeJSONObjectStart();
+    }
+
+    public function writeMapEnd() {
+        $this->writeJSONObjectEnd();
+        $this->writeJSONArrayEnd();
+    }
+
+    public function writeListBegin($elemType, $size) {
+        $this->writeJSONArrayStart();
+        $this->writeJSONString($this->getTypeNameForTypeID($elemType));
+        $this->writeJSONInteger($size);
+    }
+
+    public function writeListEnd() {
+        $this->writeJSONArrayEnd();
+    }
+
+    public function writeSetBegin($elemType, $size) {
+        $this->writeJSONArrayStart();
+        $this->writeJSONString($this->getTypeNameForTypeID($elemType));
+        $this->writeJSONInteger($size);
+    }
+
+    public function writeSetEnd() {
+        $this->writeJSONArrayEnd();
+    }
+
+    public function writeBool($bool) {
+        $this->writeJSONInteger($bool ? 1 : 0);
+    }
+
+    public function writeByte($byte) {
+        $this->writeJSONInteger($byte);
+    }
+
+    public function writeI16($i16) {
+        $this->writeJSONInteger($i16);
+    }
+
+    public function writeI32($i32) {
+        $this->writeJSONInteger($i32);
+    }
+
+    public function writeI64($i64) {
+        $this->writeJSONInteger($i64);
+    }
+
+    public function writeDouble($dub) {
+        $this->writeJSONDouble($dub);
+    }
+
+    public function writeString($str) {
+        $this->writeJSONString($str);
+    }
+
+    /**
+     * Reads the message header
+     *
+     * @param string $name Function name
+     * @param int $type message type TMessageType::CALL or TMessageType::REPLY
+     * @parem int $seqid The sequence id of this message
+     */
+    public function readMessageBegin(&$name, &$type, &$seqid) {
+        $this->readJSONArrayStart();
+
+        if ($this->readJSONInteger() != self::VERSION) {
+            throw new TProtocolException("Message contained bad version", TProtocolException::BAD_VERSION);
+        }
+
+        $name = $this->readJSONString(false);
+        $type = $this->readJSONInteger();
+        $seqid = $this->readJSONInteger();
+
+        return true;
+    }
+
+    /**
+     * Read the close of message
+     */
+    public function readMessageEnd() {
+        $this->readJSONArrayEnd();
+    }
+
+    public function readStructBegin(&$name) {
+        $this->readJSONObjectStart();
+        return 0;
+    }
+
+    public function readStructEnd() {
+        $this->readJSONObjectEnd();
+    }
+
+    public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
+        $ch = $this->reader_->peek();
+        $name = "";
+
+        if (substr($ch, 0, 1) == self::RBRACE) {
+            $fieldType = TType::STOP;
+        } else {
+            $fieldId = $this->readJSONInteger();
+            $this->readJSONObjectStart();
+            $fieldType = $this->getTypeIDForTypeName($this->readJSONString(false));
+        }
+    }
+
+    public function readFieldEnd() {
+        $this->readJSONObjectEnd();
+    }
+
+    public function readMapBegin(&$keyType, &$valType, &$size) {
+        $this->readJSONArrayStart();
+        $keyType = $this->getTypeIDForTypeName($this->readJSONString(false));
+        $valType = $this->getTypeIDForTypeName($this->readJSONString(false));
+        $size = $this->readJSONInteger();
+        $this->readJSONObjectStart();
+    }
+
+    public function readMapEnd() {
+        $this->readJSONObjectEnd();
+        $this->readJSONArrayEnd();
+    }
+
+    public function readListBegin(&$elemType, &$size) {
+        $this->readJSONArrayStart();
+        $elemType = $this->getTypeIDForTypeName($this->readJSONString(false));
+        $size = $this->readJSONInteger();
+        return true;
+    }
+
+    public function readListEnd() {
+        $this->readJSONArrayEnd();
+    }
+
+    public function readSetBegin(&$elemType, &$size) {
+        $this->readJSONArrayStart();
+        $elemType = $this->getTypeIDForTypeName($this->readJSONString(false));
+        $size = $this->readJSONInteger();
+        return true;
+    }
+
+    public function readSetEnd() {
+        $this->readJSONArrayEnd();
+    }
+
+    public function readBool(&$bool) {
+        $bool = $this->readJSONInteger() == 0 ? false : true;
+        return true;
+    }
+
+    public function readByte(&$byte) {
+        $byte = $this->readJSONInteger();
+        return true;
+    }
+
+    public function readI16(&$i16) {
+        $i16 = $this->readJSONInteger();
+        return true;
+    }
+
+    public function readI32(&$i32) {
+        $i32 = $this->readJSONInteger();
+        return true;
+    }
+
+    public function readI64(&$i64) {
+        if ( PHP_INT_SIZE === 4 ) {
+            $i64 = $this->readJSONIntegerAsString();
+        } else {
+            $i64 = $this->readJSONInteger();
+        }
+        return true;
+    }
+
+    public function readDouble(&$dub) {
+        $dub = $this->readJSONDouble();
+        return true;
+    }
+
+    public function readString(&$str) {
+        $str = $this->readJSONString(false);
+        return true;
+    }
+}
diff --git a/lib/php/lib/Thrift/Protocol/TProtocol.php b/lib/php/lib/Thrift/Protocol/TProtocol.php
new file mode 100644
index 0000000..86fff40
--- /dev/null
+++ b/lib/php/lib/Thrift/Protocol/TProtocol.php
@@ -0,0 +1,346 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ */
+
+namespace Thrift\Protocol;
+
+use Thrift\Type\TType;
+use Thrift\Exception\TProtocolException;
+
+/**
+ * Protocol base class module.
+ */
+abstract class TProtocol {
+  // The below may seem silly, but it is to get around the problem that the
+  // "instanceof" operator can only take in a T_VARIABLE and not a T_STRING
+  // or T_CONSTANT_ENCAPSED_STRING. Using "is_a()" instead of "instanceof" is
+  // a workaround but is deprecated in PHP5. This is used in the generated
+  // deserialization code.
+  static $TBINARYPROTOCOLACCELERATED = 'TBinaryProtocolAccelerated';
+
+  /**
+   * Underlying transport
+   *
+   * @var TTransport
+   */
+  protected $trans_;
+
+  /**
+   * Constructor
+   */
+  protected function __construct($trans) {
+    $this->trans_ = $trans;
+  }
+
+  /**
+   * Accessor for transport
+   *
+   * @return TTransport
+   */
+  public function getTransport() {
+    return $this->trans_;
+  }
+
+  /**
+   * Writes the message header
+   *
+   * @param string $name Function name
+   * @param int $type message type TMessageType::CALL or TMessageType::REPLY
+   * @param int $seqid The sequence id of this message
+   */
+  public abstract function writeMessageBegin($name, $type, $seqid);
+
+  /**
+   * Close the message
+   */
+  public abstract function writeMessageEnd();
+
+  /**
+   * Writes a struct header.
+   *
+   * @param string     $name Struct name
+   * @throws TException on write error
+   * @return int How many bytes written
+   */
+  public abstract function writeStructBegin($name);
+
+  /**
+   * Close a struct.
+   *
+   * @throws TException on write error
+   * @return int How many bytes written
+   */
+  public abstract function writeStructEnd();
+
+  /*
+   * Starts a field.
+   *
+   * @param string     $name Field name
+   * @param int        $type Field type
+   * @param int        $fid  Field id
+   * @throws TException on write error
+   * @return int How many bytes written
+   */
+  public abstract function writeFieldBegin($fieldName, $fieldType, $fieldId);
+
+  public abstract function writeFieldEnd();
+
+  public abstract function writeFieldStop();
+
+  public abstract function writeMapBegin($keyType, $valType, $size);
+
+  public abstract function writeMapEnd();
+
+  public abstract function writeListBegin($elemType, $size);
+
+  public abstract function writeListEnd();
+
+  public abstract function writeSetBegin($elemType, $size);
+
+  public abstract function writeSetEnd();
+
+  public abstract function writeBool($bool);
+
+  public abstract function writeByte($byte);
+
+  public abstract function writeI16($i16);
+
+  public abstract function writeI32($i32);
+
+  public abstract function writeI64($i64);
+
+  public abstract function writeDouble($dub);
+
+  public abstract function writeString($str);
+
+  /**
+   * Reads the message header
+   *
+   * @param string $name Function name
+   * @param int $type message type TMessageType::CALL or TMessageType::REPLY
+   * @parem int $seqid The sequence id of this message
+   */
+  public abstract function readMessageBegin(&$name, &$type, &$seqid);
+
+  /**
+   * Read the close of message
+   */
+  public abstract function readMessageEnd();
+
+  public abstract function readStructBegin(&$name);
+
+  public abstract function readStructEnd();
+
+  public abstract function readFieldBegin(&$name, &$fieldType, &$fieldId);
+
+  public abstract function readFieldEnd();
+
+  public abstract function readMapBegin(&$keyType, &$valType, &$size);
+
+  public abstract function readMapEnd();
+
+  public abstract function readListBegin(&$elemType, &$size);
+
+  public abstract function readListEnd();
+
+  public abstract function readSetBegin(&$elemType, &$size);
+
+  public abstract function readSetEnd();
+
+  public abstract function readBool(&$bool);
+
+  public abstract function readByte(&$byte);
+
+  public abstract function readI16(&$i16);
+
+  public abstract function readI32(&$i32);
+
+  public abstract function readI64(&$i64);
+
+  public abstract function readDouble(&$dub);
+
+  public abstract function readString(&$str);
+
+  /**
+   * The skip function is a utility to parse over unrecognized date without
+   * causing corruption.
+   *
+   * @param TType $type What type is it
+   */
+  public function skip($type) {
+    switch ($type) {
+    case TType::BOOL:
+      return $this->readBool($bool);
+    case TType::BYTE:
+      return $this->readByte($byte);
+    case TType::I16:
+      return $this->readI16($i16);
+    case TType::I32:
+      return $this->readI32($i32);
+    case TType::I64:
+      return $this->readI64($i64);
+    case TType::DOUBLE:
+      return $this->readDouble($dub);
+    case TType::STRING:
+      return $this->readString($str);
+    case TType::STRUCT:
+      {
+        $result = $this->readStructBegin($name);
+        while (true) {
+          $result += $this->readFieldBegin($name, $ftype, $fid);
+          if ($ftype == TType::STOP) {
+            break;
+          }
+          $result += $this->skip($ftype);
+          $result += $this->readFieldEnd();
+        }
+        $result += $this->readStructEnd();
+        return $result;
+      }
+    case TType::MAP:
+      {
+        $result = $this->readMapBegin($keyType, $valType, $size);
+        for ($i = 0; $i < $size; $i++) {
+          $result += $this->skip($keyType);
+          $result += $this->skip($valType);
+        }
+        $result += $this->readMapEnd();
+        return $result;
+      }
+    case TType::SET:
+      {
+        $result = $this->readSetBegin($elemType, $size);
+        for ($i = 0; $i < $size; $i++) {
+          $result += $this->skip($elemType);
+        }
+        $result += $this->readSetEnd();
+        return $result;
+      }
+    case TType::LST:
+      {
+        $result = $this->readListBegin($elemType, $size);
+        for ($i = 0; $i < $size; $i++) {
+          $result += $this->skip($elemType);
+        }
+        $result += $this->readListEnd();
+        return $result;
+      }
+    default:
+      throw new TProtocolException('Unknown field type: '.$type,
+                                   TProtocolException::INVALID_DATA);
+    }
+  }
+
+  /**
+   * Utility for skipping binary data
+   *
+   * @param TTransport $itrans TTransport object
+   * @param int        $type   Field type
+   */
+  public static function skipBinary($itrans, $type) {
+    switch ($type) {
+    case TType::BOOL:
+      return $itrans->readAll(1);
+    case TType::BYTE:
+      return $itrans->readAll(1);
+    case TType::I16:
+      return $itrans->readAll(2);
+    case TType::I32:
+      return $itrans->readAll(4);
+    case TType::I64:
+      return $itrans->readAll(8);
+    case TType::DOUBLE:
+      return $itrans->readAll(8);
+    case TType::STRING:
+      $len = unpack('N', $itrans->readAll(4));
+      $len = $len[1];
+      if ($len > 0x7fffffff) {
+        $len = 0 - (($len - 1) ^ 0xffffffff);
+      }
+      return 4 + $itrans->readAll($len);
+    case TType::STRUCT:
+      {
+        $result = 0;
+        while (true) {
+          $ftype = 0;
+          $fid = 0;
+          $data = $itrans->readAll(1);
+          $arr = unpack('c', $data);
+          $ftype = $arr[1];
+          if ($ftype == TType::STOP) {
+            break;
+          }
+          // I16 field id
+          $result += $itrans->readAll(2);
+          $result += self::skipBinary($itrans, $ftype);
+        }
+        return $result;
+      }
+    case TType::MAP:
+      {
+        // Ktype
+        $data = $itrans->readAll(1);
+        $arr = unpack('c', $data);
+        $ktype = $arr[1];
+        // Vtype
+        $data = $itrans->readAll(1);
+        $arr = unpack('c', $data);
+        $vtype = $arr[1];
+        // Size
+        $data = $itrans->readAll(4);
+        $arr = unpack('N', $data);
+        $size = $arr[1];
+        if ($size > 0x7fffffff) {
+          $size = 0 - (($size - 1) ^ 0xffffffff);
+        }
+        $result = 6;
+        for ($i = 0; $i < $size; $i++) {
+          $result += self::skipBinary($itrans, $ktype);
+          $result += self::skipBinary($itrans, $vtype);
+        }
+        return $result;
+      }
+    case TType::SET:
+    case TType::LST:
+      {
+        // Vtype
+        $data = $itrans->readAll(1);
+        $arr = unpack('c', $data);
+        $vtype = $arr[1];
+        // Size
+        $data = $itrans->readAll(4);
+        $arr = unpack('N', $data);
+        $size = $arr[1];
+        if ($size > 0x7fffffff) {
+          $size = 0 - (($size - 1) ^ 0xffffffff);
+        }
+        $result = 5;
+        for ($i = 0; $i < $size; $i++) {
+          $result += self::skipBinary($itrans, $vtype);
+        }
+        return $result;
+      }
+    default:
+      throw new TProtocolException('Unknown field type: '.$type,
+                                   TProtocolException::INVALID_DATA);
+    }
+  }
+}
diff --git a/lib/php/lib/Thrift/Serializer/TBinarySerializer.php b/lib/php/lib/Thrift/Serializer/TBinarySerializer.php
new file mode 100644
index 0000000..2a7cc3e
--- /dev/null
+++ b/lib/php/lib/Thrift/Serializer/TBinarySerializer.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.protocol
+ * @author: rmarin (marin.radu@facebook.com)
+ */
+
+namespace Thrift\Serializer;
+
+use Thrift\Transport\TMemoryBuffer;
+use Thrift\Protocol\TBinaryProtocolAccelerated;
+use Thrift\Type\TMessageType;
+
+/**
+ * Utility class for serializing and deserializing
+ * a thrift object using TBinaryProtocolAccelerated.
+ */
+class TBinarySerializer {
+
+  // NOTE(rmarin): Because thrift_protocol_write_binary
+  // adds a begin message prefix, you cannot specify
+  // a transport in which to serialize an object. It has to
+  // be a string. Otherwise we will break the compatibility with
+  // normal deserialization.
+  public static function serialize($object) {
+    $transport = new TMemoryBuffer();
+    $protocol = new TBinaryProtocolAccelerated($transport);
+    if (function_exists('thrift_protocol_write_binary')) {
+      thrift_protocol_write_binary($protocol, $object->getName(),
+                                   TMessageType::REPLY, $object,
+                                   0, $protocol->isStrictWrite());
+
+      $protocol->readMessageBegin($unused_name, $unused_type,
+                                  $unused_seqid);
+    } else {
+      $object->write($protocol);
+    }
+    $protocol->getTransport()->flush();
+    return $transport->getBuffer();
+  }
+
+  public static function deserialize($string_object, $class_name) {
+     $transport = new TMemoryBuffer();
+     $protocol = new TBinaryProtocolAccelerated($transport);
+     if (function_exists('thrift_protocol_read_binary')) {
+       $protocol->writeMessageBegin('', TMessageType::REPLY, 0);
+       $transport->write($string_object);
+       return thrift_protocol_read_binary($protocol, $class_name,
+                                          $protocol->isStrictRead());
+     } else {
+       $transport->write($string_object);
+       $object = new $class_name();
+       $object->read($protocol);
+       return $object;
+     }
+  }
+}
diff --git a/lib/php/lib/Thrift/Server/TForkingServer.php b/lib/php/lib/Thrift/Server/TForkingServer.php
new file mode 100644
index 0000000..6fca305
--- /dev/null
+++ b/lib/php/lib/Thrift/Server/TForkingServer.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Thrift\Server;
+
+use Thrift\Server\TServer;
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TException;
+use Thrift\Exception\TTransportException;
+
+/**
+ * A forking implementation of a Thrift server.
+ *
+ * @package thrift.server
+ */
+class TForkingServer extends TServer {
+  /**
+   * Flag for the main serving loop
+   *
+   * @var bool
+   */
+  private $stop_ = false;
+
+  /**
+   * List of children.
+   *
+   * @var array
+   */
+  protected $children_ = array();
+
+  /**
+   * Listens for new client using the supplied
+   * transport. We fork when a new connection
+   * arrives.
+   *
+   * @return void
+   */
+  public function serve() {
+    $this->transport_->listen();
+
+    while (!$this->stop_) {
+      try {
+        $transport = $this->transport_->accept();
+
+        if ($transport != null) {
+          $pid = pcntl_fork();
+
+          if ($pid > 0) {
+            $this->handleParent($transport, $pid);
+          }
+          else if ($pid === 0) {
+            $this->handleChild($transport);
+          }
+          else {
+            throw new TException('Failed to fork');
+          }
+        }
+      }
+      catch (TTransportException $e) { }
+
+      $this->collectChildren();
+    }
+  }
+
+  /**
+   * Code run by the parent
+   *
+   * @param TTransport $transport
+   * @param int $pid
+   * @return void
+   */
+  private function handleParent(TTransport $transport, $pid) {
+    $this->children_[$pid] = $transport;
+  }
+
+  /**
+   * Code run by the child.
+   *
+   * @param TTransport $transport
+   * @return void
+   */
+  private function handleChild(TTransport $transport) {
+    try {
+      $inputTransport = $this->inputTransportFactory_->getTransport($transport);
+      $outputTransport = $this->outputTransportFactory_->getTransport($transport);
+      $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport);
+      $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport);
+      while ($this->processor_->process($inputProtocol, $outputProtocol)) { }
+      @$transport->close();
+    }
+    catch (TTransportException $e) { }
+
+    exit(0);
+  }
+
+  /**
+   * Collects any children we may have
+   *
+   * @return void
+   */
+  private function collectChildren() {
+    foreach ($this->children_ as $pid => $transport) {
+      if (pcntl_waitpid($pid, $status, WNOHANG) > 0) {
+        unset($this->children_[$pid]);
+        if ($transport) @$transport->close();
+      }
+    }
+  }
+
+  /**
+   * Stops the server running. Kills the transport
+   * and then stops the main serving loop
+   *
+   * @return void
+   */
+  public function stop() {
+    $this->transport_->close();
+    $this->stop_ = true;
+  }
+}
diff --git a/lib/php/lib/Thrift/Server/TServer.php b/lib/php/lib/Thrift/Server/TServer.php
new file mode 100644
index 0000000..343bf4b
--- /dev/null
+++ b/lib/php/lib/Thrift/Server/TServer.php
@@ -0,0 +1,101 @@
+<?php
+
+namespace Thrift\Server;
+
+use Thrift\Server\TServerTransport;
+use Thrift\Factory\TTransportFactory;
+use Thrift\Factory\TProtocolFactory;
+
+/**
+ * Generic class for a Thrift server.
+ *
+ * @package thrift.server
+ */
+abstract class TServer {
+
+  /**
+   * Processor to handle new clients
+   *
+   * @var TProcessor
+   */
+  protected $processor_;
+
+  /**
+   * Server transport to be used for listening
+   * and accepting new clients
+   *
+   * @var TServerTransport
+   */
+  protected $transport_;
+
+  /**
+   * Input transport factory
+   *
+   * @var TTransportFactory
+   */
+  protected $inputTransportFactory_;
+
+  /**
+   * Output transport factory
+   *
+   * @var TTransportFactory
+   */
+  protected $outputTransportFactory_;
+
+  /**
+   * Input protocol factory
+   *
+   * @var TProtocolFactory
+   */
+  protected $inputProtocolFactory_;
+
+  /**
+   * Output protocol factory
+   *
+   * @var TProtocolFactory
+   */
+  protected $outputProtocolFactory_;
+
+  /**
+   * Sets up all the factories, etc
+   *
+   * @param object $processor
+   * @param TServerTransport $transport
+   * @param TTransportFactory $inputTransportFactory
+   * @param TTransportFactory $outputTransportFactory
+   * @param TProtocolFactory $inputProtocolFactory
+   * @param TProtocolFactory $outputProtocolFactory
+   * @return void
+   */
+  public function __construct($processor,
+                              TServerTransport $transport,
+                              TTransportFactory $inputTransportFactory,
+                              TTransportFactory $outputTransportFactory,
+                              TProtocolFactory $inputProtocolFactory,
+                              TProtocolFactory $outputProtocolFactory) {
+    $this->processor_ = $processor;
+    $this->transport_ = $transport;
+    $this->inputTransportFactory_ = $inputTransportFactory;
+    $this->outputTransportFactory_ = $outputTransportFactory;
+    $this->inputProtocolFactory_ = $inputProtocolFactory;
+    $this->outputProtocolFactory_ = $outputProtocolFactory;
+  }
+
+  /**
+   * Serves the server. This should never return
+   * unless a problem permits it to do so or it
+   * is interrupted intentionally
+   *
+   * @abstract
+   * @return void
+   */
+  abstract public function serve();
+
+  /**
+   * Stops the server serving
+   *
+   * @abstract
+   * @return void
+   */
+  abstract public function stop();
+}
diff --git a/lib/php/lib/Thrift/Server/TServerSocket.php b/lib/php/lib/Thrift/Server/TServerSocket.php
new file mode 100644
index 0000000..00a6fb9
--- /dev/null
+++ b/lib/php/lib/Thrift/Server/TServerSocket.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Thrift\Server;
+
+use Thrift\Server\TServerTransport;
+use Thrift\Transport\TSocket;
+
+/**
+ * Socket implementation of a server agent.
+ *
+ * @package thrift.transport
+ */
+class TServerSocket extends TServerTransport {
+
+  /**
+   * Handle for the listener socket
+   *
+   * @var resource
+   */
+  private $listener_;
+
+  /**
+   * Port for the listener to listen on
+   *
+   * @var int
+   */
+  private $port_;
+
+  /**
+   * Timeout when listening for a new client
+   *
+   * @var int
+   */
+  private $acceptTimeout_ = 30000;
+
+  /**
+   * Host to listen on
+   *
+   * @var string
+   */
+  private $host_;
+
+  /**
+   * ServerSocket constructor
+   *
+   * @param string $host        Host to listen on
+   * @param int $port           Port to listen on
+   * @return void
+   */
+  public function __construct($host = 'localhost', $port = 9090) {
+    $this->host_ = $host;
+    $this->port_ = $port;
+  }
+
+  /**
+   * Sets the accept timeout
+   *
+   * @param int $acceptTimeout
+   * @return void
+   */
+  public function setAcceptTimeout($acceptTimeout) {
+    $this->acceptTimeout_ = $acceptTimeout;
+  }
+
+  /**
+   * Opens a new socket server handle
+   *
+   * @return void
+   */
+  public function listen() {
+    $this->listener_ = stream_socket_server('tcp://' . $this->host_ . ':' . $this->port_);
+  }
+
+  /**
+   * Closes the socket server handle
+   *
+   * @return void
+   */
+  public function close() {
+    @fclose($this->listener_);
+    $this->listener_ = null;
+  }
+
+  /**
+   * Implementation of accept. If not client is accepted in the given time
+   *
+   * @return TSocket
+   */
+  protected function acceptImpl() {
+    $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0);
+    if(!$handle) return null;
+
+    $socket = new TSocket();
+    $socket->setHandle($handle);
+
+    return $socket;
+  }
+}
diff --git a/lib/php/lib/Thrift/Server/TServerTransport.php b/lib/php/lib/Thrift/Server/TServerTransport.php
new file mode 100644
index 0000000..5324712
--- /dev/null
+++ b/lib/php/lib/Thrift/Server/TServerTransport.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Thrift\Server;
+
+use Thrift\Exception\TTransportException;
+
+/**
+ * Generic class for Server agent.
+ *
+ * @package thrift.transport
+ */
+abstract class TServerTransport {
+  /**
+   * List for new clients
+   *
+   * @abstract
+   * @return void
+   */
+  abstract public function listen();
+
+  /**
+   * Close the server
+   *
+   * @abstract
+   * @return void
+   */
+  abstract public function close();
+
+  /**
+   * Subclasses should use this to implement
+   * accept.
+   *
+   * @abstract
+   * @return TTransport
+   */
+  protected abstract function acceptImpl();
+
+  /**
+   * Uses the accept implemtation. If null is returned, an
+   * exception is thrown.
+   *
+   * @throws TTransportException
+   * @return TTransport
+   */
+  public function accept() {
+    $transport = $this->acceptImpl();
+
+    if ($transport == null) {
+      throw new TTransportException("accept() may not return NULL");
+    }
+
+    return $transport;
+  }
+}
diff --git a/lib/php/lib/Thrift/Server/TSimpleServer.php b/lib/php/lib/Thrift/Server/TSimpleServer.php
new file mode 100644
index 0000000..790e48f
--- /dev/null
+++ b/lib/php/lib/Thrift/Server/TSimpleServer.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Thrift\Server;
+
+use Thrift\Server\TServer;
+use Thrift\Exception\TTransportException;
+
+/**
+ * Simple implemtation of a Thrift server.
+ *
+ * @package thrift.server
+ */
+class TSimpleServer extends TServer {
+  /**
+   * Flag for the main serving loop
+   *
+   * @var bool
+   */
+  private $stop_ = false;
+
+  /**
+   * Listens for new client using the supplied
+   * transport. It handles TTransportExceptions
+   * to avoid timeouts etc killing it
+   *
+   * @return void
+   */
+  public function serve() {
+    $this->transport_->listen();
+
+    while (!$this->stop_) {
+      try {
+        $transport = $this->transport_->accept();
+
+        if ($transport != null) {
+          $inputTransport = $this->inputTransportFactory_->getTransport($transport);
+          $outputTransport = $this->outputTransportFactory_->getTransport($transport);
+          $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport);
+          $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport);
+          while ($this->processor_->process($inputProtocol, $outputProtocol)) { }
+        }
+      }
+      catch (TTransportException $e) { }
+    }
+  }
+
+  /**
+   * Stops the server running. Kills the transport
+   * and then stops the main serving loop
+   *
+   * @return void
+   */
+  public function stop() {
+    $this->transport_->close();
+    $this->stop_ = true;
+  }
+}
diff --git a/lib/php/lib/Thrift/StringFunc/Core.php b/lib/php/lib/Thrift/StringFunc/Core.php
new file mode 100644
index 0000000..e38a5b2
--- /dev/null
+++ b/lib/php/lib/Thrift/StringFunc/Core.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * 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.
+ *
+ */
+
+namespace Thrift\StringFunc;
+
+use Thrift\StringFunc\TStringFunc;
+
+class Core implements TStringFunc {
+    public function substr($str, $start, $length = null) {
+        // specifying a null $length would return an empty string
+        if($length === null) {
+            return substr($str, $start);
+        }
+        return substr($str, $start, $length);
+    }
+
+    public function strlen($str) {
+        return strlen($str);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/StringFunc/Mbstring.php b/lib/php/lib/Thrift/StringFunc/Mbstring.php
new file mode 100644
index 0000000..c1ace13
--- /dev/null
+++ b/lib/php/lib/Thrift/StringFunc/Mbstring.php
@@ -0,0 +1,45 @@
+<?php
+/*
+ * 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.
+ *
+ */
+
+namespace Thrift\StringFunc;
+
+use Thrift\StringFunc\TStringFunc;
+
+class Mbstring implements TStringFunc {
+    public function substr($str, $start, $length = null) {
+        /**
+         * We need to set the charset parameter, which is the second
+         * optional parameter and the first optional parameter can't
+         * be null or false as a "magic" value because that would
+         * cause an empty string to be returned, so we need to
+         * actually calculate the proper length value.
+         */
+        if($length === null) {
+            $length = $this->strlen($str) - $start;
+        }
+
+        return mb_substr($str, $start, $length, '8bit');
+    }
+
+    public function strlen($str) {
+        return mb_strlen($str, '8bit');
+    }
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/StringFunc/TStringFunc.php b/lib/php/lib/Thrift/StringFunc/TStringFunc.php
new file mode 100644
index 0000000..c5bb390
--- /dev/null
+++ b/lib/php/lib/Thrift/StringFunc/TStringFunc.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * 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.
+ *
+ */
+
+namespace Thrift\StringFunc;
+
+interface TStringFunc {
+    public function substr($str, $start, $length = null);
+    public function strlen($str);
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Transport/TBufferedTransport.php b/lib/php/lib/Thrift/Transport/TBufferedTransport.php
new file mode 100644
index 0000000..0d3ad98
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TBufferedTransport.php
@@ -0,0 +1,165 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Buffered transport. Stores data to an internal buffer that it doesn't
+ * actually write out until flush is called. For reading, we do a greedy
+ * read and then serve data out of the internal buffer.
+ *
+ * @package thrift.transport
+ */
+class TBufferedTransport extends TTransport {
+
+  /**
+   * Constructor. Creates a buffered transport around an underlying transport
+   */
+  public function __construct($transport=null, $rBufSize=512, $wBufSize=512) {
+    $this->transport_ = $transport;
+    $this->rBufSize_ = $rBufSize;
+    $this->wBufSize_ = $wBufSize;
+  }
+
+  /**
+   * The underlying transport
+   *
+   * @var TTransport
+   */
+  protected $transport_ = null;
+
+  /**
+   * The receive buffer size
+   *
+   * @var int
+   */
+  protected $rBufSize_ = 512;
+
+  /**
+   * The write buffer size
+   *
+   * @var int
+   */
+  protected $wBufSize_ = 512;
+
+  /**
+   * The write buffer.
+   *
+   * @var string
+   */
+  protected $wBuf_ = '';
+
+  /**
+   * The read buffer.
+   *
+   * @var string
+   */
+  protected $rBuf_ = '';
+
+  public function isOpen() {
+    return $this->transport_->isOpen();
+  }
+
+  public function open() {
+    $this->transport_->open();
+  }
+
+  public function close() {
+    $this->transport_->close();
+  }
+
+  public function putBack($data) {
+    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
+      $this->rBuf_ = $data;
+    } else {
+      $this->rBuf_ = ($data . $this->rBuf_);
+    }
+  }
+
+  /**
+   * The reason that we customize readAll here is that the majority of PHP
+   * streams are already internally buffered by PHP. The socket stream, for
+   * example, buffers internally and blocks if you call read with $len greater
+   * than the amount of data available, unlike recv() in C.
+   *
+   * Therefore, use the readAll method of the wrapped transport inside
+   * the buffered readAll.
+   */
+  public function readAll($len) {
+    $have = TStringFuncFactory::create()->strlen($this->rBuf_);
+    if ($have == 0) {
+      $data = $this->transport_->readAll($len);
+    } else if ($have < $len) {
+      $data = $this->rBuf_;
+      $this->rBuf_ = '';
+      $data .= $this->transport_->readAll($len - $have);
+    } else if ($have == $len) {
+      $data = $this->rBuf_;
+      $this->rBuf_ = '';
+    } else if ($have > $len) {
+      $data = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
+      $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
+    }
+    return $data;
+  }
+
+  public function read($len) {
+    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
+      $this->rBuf_ = $this->transport_->read($this->rBufSize_);
+    }
+
+    if (TStringFuncFactory::create()->strlen($this->rBuf_) <= $len) {
+      $ret = $this->rBuf_;
+      $this->rBuf_ = '';
+      return $ret;
+    }
+
+    $ret = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
+    $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
+    return $ret;
+  }
+
+  public function write($buf) {
+    $this->wBuf_ .= $buf;
+    if (TStringFuncFactory::create()->strlen($this->wBuf_) >= $this->wBufSize_) {
+      $out = $this->wBuf_;
+
+      // Note that we clear the internal wBuf_ prior to the underlying write
+      // to ensure we're in a sane state (i.e. internal buffer cleaned)
+      // if the underlying write throws up an exception
+      $this->wBuf_ = '';
+      $this->transport_->write($out);
+    }
+  }
+
+  public function flush() {
+    if (TStringFuncFactory::create()->strlen($this->wBuf_) > 0) {
+      $this->transport_->write($this->wBuf_);
+      $this->wBuf_ = '';
+    }
+    $this->transport_->flush();
+  }
+
+}
diff --git a/lib/php/lib/Thrift/Transport/TFramedTransport.php b/lib/php/lib/Thrift/Transport/TFramedTransport.php
new file mode 100644
index 0000000..d80d548
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TFramedTransport.php
@@ -0,0 +1,183 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Framed transport. Writes and reads data in chunks that are stamped with
+ * their length.
+ *
+ * @package thrift.transport
+ */
+class TFramedTransport extends TTransport {
+
+  /**
+   * Underlying transport object.
+   *
+   * @var TTransport
+   */
+  private $transport_;
+
+  /**
+   * Buffer for read data.
+   *
+   * @var string
+   */
+  private $rBuf_;
+
+  /**
+   * Buffer for queued output data
+   *
+   * @var string
+   */
+  private $wBuf_;
+
+  /**
+   * Whether to frame reads
+   *
+   * @var bool
+   */
+  private $read_;
+
+  /**
+   * Whether to frame writes
+   *
+   * @var bool
+   */
+  private $write_;
+
+  /**
+   * Constructor.
+   *
+   * @param TTransport $transport Underlying transport
+   */
+  public function __construct($transport=null, $read=true, $write=true) {
+    $this->transport_ = $transport;
+    $this->read_ = $read;
+    $this->write_ = $write;
+  }
+
+  public function isOpen() {
+    return $this->transport_->isOpen();
+  }
+
+  public function open() {
+    $this->transport_->open();
+  }
+
+  public function close() {
+    $this->transport_->close();
+  }
+
+  /**
+   * Reads from the buffer. When more data is required reads another entire
+   * chunk and serves future reads out of that.
+   *
+   * @param int $len How much data
+   */
+  public function read($len) {
+    if (!$this->read_) {
+      return $this->transport_->read($len);
+    }
+
+    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
+      $this->readFrame();
+    }
+
+    // Just return full buff
+    if ($len >= TStringFuncFactory::create()->strlen($this->rBuf_)) {
+      $out = $this->rBuf_;
+      $this->rBuf_ = null;
+      return $out;
+    }
+
+    // Return TStringFuncFactory::create()->substr
+    $out = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
+    $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
+    return $out;
+  }
+
+  /**
+   * Put previously read data back into the buffer
+   *
+   * @param string $data data to return
+   */
+  public function putBack($data) {
+    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
+      $this->rBuf_ = $data;
+    } else {
+      $this->rBuf_ = ($data . $this->rBuf_);
+    }
+  }
+
+  /**
+   * Reads a chunk of data into the internal read buffer.
+   */
+  private function readFrame() {
+    $buf = $this->transport_->readAll(4);
+    $val = unpack('N', $buf);
+    $sz = $val[1];
+
+    $this->rBuf_ = $this->transport_->readAll($sz);
+  }
+
+  /**
+   * Writes some data to the pending output buffer.
+   *
+   * @param string $buf The data
+   * @param int    $len Limit of bytes to write
+   */
+  public function write($buf, $len=null) {
+    if (!$this->write_) {
+      return $this->transport_->write($buf, $len);
+    }
+
+    if ($len !== null && $len < TStringFuncFactory::create()->strlen($buf)) {
+      $buf = TStringFuncFactory::create()->substr($buf, 0, $len);
+    }
+    $this->wBuf_ .= $buf;
+  }
+
+  /**
+   * Writes the output buffer to the stream in the format of a 4-byte length
+   * followed by the actual data.
+   */
+  public function flush() {
+    if (!$this->write_ || TStringFuncFactory::create()->strlen($this->wBuf_) == 0) {
+      return $this->transport_->flush();
+    }
+
+    $out = pack('N', TStringFuncFactory::create()->strlen($this->wBuf_));
+    $out .= $this->wBuf_;
+
+    // Note that we clear the internal wBuf_ prior to the underlying write
+    // to ensure we're in a sane state (i.e. internal buffer cleaned)
+    // if the underlying write throws up an exception
+    $this->wBuf_ = '';
+    $this->transport_->write($out);
+    $this->transport_->flush();
+  }
+
+}
diff --git a/lib/php/lib/Thrift/Transport/THttpClient.php b/lib/php/lib/Thrift/Transport/THttpClient.php
new file mode 100644
index 0000000..87f2871
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/THttpClient.php
@@ -0,0 +1,205 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * HTTP client for Thrift
+ *
+ * @package thrift.transport
+ */
+class THttpClient extends TTransport {
+
+  /**
+   * The host to connect to
+   *
+   * @var string
+   */
+  protected $host_;
+
+  /**
+   * The port to connect on
+   *
+   * @var int
+   */
+  protected $port_;
+
+  /**
+   * The URI to request
+   *
+   * @var string
+   */
+  protected $uri_;
+
+  /**
+   * The scheme to use for the request, i.e. http, https
+   *
+   * @var string
+   */
+  protected $scheme_;
+
+  /**
+   * Buffer for the HTTP request data
+   *
+   * @var string
+   */
+  protected $buf_;
+
+  /**
+   * Input socket stream.
+   *
+   * @var resource
+   */
+  protected $handle_;
+
+  /**
+   * Read timeout
+   *
+   * @var float
+   */
+  protected $timeout_;
+
+  /**
+   * Make a new HTTP client.
+   *
+   * @param string $host
+   * @param int    $port
+   * @param string $uri
+   */
+  public function __construct($host, $port=80, $uri='', $scheme = 'http') {
+    if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri{0} != '/')) {
+      $uri = '/'.$uri;
+    }
+    $this->scheme_ = $scheme;
+    $this->host_ = $host;
+    $this->port_ = $port;
+    $this->uri_ = $uri;
+    $this->buf_ = '';
+    $this->handle_ = null;
+    $this->timeout_ = null;
+  }
+
+  /**
+   * Set read timeout
+   *
+   * @param float $timeout
+   */
+  public function setTimeoutSecs($timeout) {
+    $this->timeout_ = $timeout;
+  }
+
+  /**
+   * Whether this transport is open.
+   *
+   * @return boolean true if open
+   */
+  public function isOpen() {
+    return true;
+  }
+
+  /**
+   * Open the transport for reading/writing
+   *
+   * @throws TTransportException if cannot open
+   */
+  public function open() {}
+
+  /**
+   * Close the transport.
+   */
+  public function close() {
+    if ($this->handle_) {
+      @fclose($this->handle_);
+      $this->handle_ = null;
+    }
+  }
+
+  /**
+   * Read some data into the array.
+   *
+   * @param int    $len How much to read
+   * @return string The data that has been read
+   * @throws TTransportException if cannot read any more data
+   */
+  public function read($len) {
+    $data = @fread($this->handle_, $len);
+    if ($data === FALSE || $data === '') {
+      $md = stream_get_meta_data($this->handle_);
+      if ($md['timed_out']) {
+        throw new TTransportException('THttpClient: timed out reading '.$len.' bytes from '.$this->host_.':'.$this->port_.$this->uri_, TTransportException::TIMED_OUT);
+      } else {
+        throw new TTransportException('THttpClient: Could not read '.$len.' bytes from '.$this->host_.':'.$this->port_.$this->uri_, TTransportException::UNKNOWN);
+      }
+    }
+    return $data;
+  }
+
+  /**
+   * Writes some data into the pending buffer
+   *
+   * @param string $buf  The data to write
+   * @throws TTransportException if writing fails
+   */
+  public function write($buf) {
+    $this->buf_ .= $buf;
+  }
+
+  /**
+   * Opens and sends the actual request over the HTTP connection
+   *
+   * @throws TTransportException if a writing error occurs
+   */
+  public function flush() {
+    // God, PHP really has some esoteric ways of doing simple things.
+    $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
+
+    $headers = array('Host: '.$host,
+                     'Accept: application/x-thrift',
+                     'User-Agent: PHP/THttpClient',
+                     'Content-Type: application/x-thrift',
+                     'Content-Length: '.TStringFuncFactory::create()->strlen($this->buf_));
+
+    $options = array('method' => 'POST',
+                     'header' => implode("\r\n", $headers),
+                     'max_redirects' => 1,
+                     'content' => $this->buf_);
+    if ($this->timeout_ > 0) {
+      $options['timeout'] = $this->timeout_;
+    }
+    $this->buf_ = '';
+
+    $contextid = stream_context_create(array('http' => $options));
+    $this->handle_ = @fopen($this->scheme_.'://'.$host.$this->uri_, 'r', false, $contextid);
+
+    // Connect failed?
+    if ($this->handle_ === FALSE) {
+      $this->handle_ = null;
+      $error = 'THttpClient: Could not connect to '.$host.$this->uri_;
+      throw new TTransportException($error, TTransportException::NOT_OPEN);
+    }
+  }
+
+}
diff --git a/lib/php/lib/Thrift/Transport/TMemoryBuffer.php b/lib/php/lib/Thrift/Transport/TMemoryBuffer.php
new file mode 100644
index 0000000..cfe5e0e
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TMemoryBuffer.php
@@ -0,0 +1,87 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * A memory buffer is a tranpsort that simply reads from and writes to an
+ * in-memory string buffer. Anytime you call write on it, the data is simply
+ * placed into a buffer, and anytime you call read, data is read from that
+ * buffer.
+ *
+ * @package thrift.transport
+ */
+class TMemoryBuffer extends TTransport {
+
+  /**
+   * Constructor. Optionally pass an initial value
+   * for the buffer.
+   */
+  public function __construct($buf = '') {
+    $this->buf_ = $buf;
+  }
+
+  protected $buf_ = '';
+
+  public function isOpen() {
+    return true;
+  }
+
+  public function open() {}
+
+  public function close() {}
+
+  public function write($buf) {
+    $this->buf_ .= $buf;
+  }
+
+  public function read($len) {
+    if (TStringFuncFactory::create()->strlen($this->buf_) === 0) {
+      throw new TTransportException('TMemoryBuffer: Could not read ' .
+                                    $len . ' bytes from buffer.',
+                                    TTransportException::UNKNOWN);
+    }
+
+    if (TStringFuncFactory::create()->strlen($this->buf_) <= $len) {
+      $ret = $this->buf_;
+      $this->buf_ = '';
+      return $ret;
+    }
+
+    $ret = TStringFuncFactory::create()->substr($this->buf_, 0, $len);
+    $this->buf_ = TStringFuncFactory::create()->substr($this->buf_, $len);
+
+    return $ret;
+  }
+
+  function getBuffer() {
+    return $this->buf_;
+  }
+
+  public function available() {
+    return TStringFuncFactory::create()->strlen($this->buf_);
+  }
+}
diff --git a/lib/php/lib/Thrift/Transport/TNullTransport.php b/lib/php/lib/Thrift/Transport/TNullTransport.php
new file mode 100644
index 0000000..4bf10ed
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TNullTransport.php
@@ -0,0 +1,50 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TTransportException;
+
+/**
+ * Transport that only accepts writes and ignores them.
+ * This is useful for measuring the serialized size of structures.
+ *
+ * @package thrift.transport
+ */
+class TNullTransport extends TTransport {
+
+  public function isOpen() {
+    return true;
+  }
+
+  public function open() {}
+
+  public function close() {}
+
+  public function read($len) {
+    throw new TTransportException("Can't read from TNullTransport.");
+  }
+
+  public function write($buf) {}
+
+}
diff --git a/lib/php/lib/Thrift/Transport/TPhpStream.php b/lib/php/lib/Thrift/Transport/TPhpStream.php
new file mode 100644
index 0000000..691d0cf
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TPhpStream.php
@@ -0,0 +1,114 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Php stream transport. Reads to and writes from the php standard streams
+ * php://input and php://output
+ *
+ * @package thrift.transport
+ */
+class TPhpStream extends TTransport {
+
+  const MODE_R = 1;
+  const MODE_W = 2;
+
+  private $inStream_ = null;
+
+  private $outStream_ = null;
+
+  private $read_ = false;
+
+  private $write_ = false;
+
+  public function __construct($mode) {
+    $this->read_ = $mode & self::MODE_R;
+    $this->write_ = $mode & self::MODE_W;
+  }
+
+  public function open() {
+    if ($this->read_) {
+      $this->inStream_ = @fopen(self::inStreamName(), 'r');
+      if (!is_resource($this->inStream_)) {
+        throw new TException('TPhpStream: Could not open php://input');
+      }
+    }
+    if ($this->write_) {
+      $this->outStream_ = @fopen('php://output', 'w');
+      if (!is_resource($this->outStream_)) {
+        throw new TException('TPhpStream: Could not open php://output');
+      }
+    }
+  }
+
+  public function close() {
+    if ($this->read_) {
+      @fclose($this->inStream_);
+      $this->inStream_ = null;
+    }
+    if ($this->write_) {
+      @fclose($this->outStream_);
+      $this->outStream_ = null;
+    }
+  }
+
+  public function isOpen() {
+    return
+      (!$this->read_ || is_resource($this->inStream_)) &&
+      (!$this->write_ || is_resource($this->outStream_));
+  }
+
+  public function read($len) {
+    $data = @fread($this->inStream_, $len);
+    if ($data === FALSE || $data === '') {
+      throw new TException('TPhpStream: Could not read '.$len.' bytes');
+    }
+    return $data;
+  }
+
+  public function write($buf) {
+    while (TStringFuncFactory::create()->strlen($buf) > 0) {
+      $got = @fwrite($this->outStream_, $buf);
+      if ($got === 0 || $got === FALSE) {
+        throw new TException('TPhpStream: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes');
+      }
+      $buf = TStringFuncFactory::create()->substr($buf, $got);
+    }
+  }
+
+  public function flush() {
+    @fflush($this->outStream_);
+  }
+
+  private static function inStreamName() {
+    if (php_sapi_name() == 'cli') {
+      return 'php://stdin';
+    }
+    return 'php://input';
+  }
+
+}
diff --git a/lib/php/lib/Thrift/Transport/TSocket.php b/lib/php/lib/Thrift/Transport/TSocket.php
new file mode 100644
index 0000000..3ad3bf7
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TSocket.php
@@ -0,0 +1,326 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TTransport;
+use Thrift\Exception\TException;
+use Thrift\Exception\TTransportException;
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Sockets implementation of the TTransport interface.
+ *
+ * @package thrift.transport
+ */
+class TSocket extends TTransport {
+
+  /**
+   * Handle to PHP socket
+   *
+   * @var resource
+   */
+  private $handle_ = null;
+
+  /**
+   * Remote hostname
+   *
+   * @var string
+   */
+  protected $host_ = 'localhost';
+
+  /**
+   * Remote port
+   *
+   * @var int
+   */
+  protected $port_ = '9090';
+
+  /**
+   * Send timeout in seconds.
+   *
+   * Combined with sendTimeoutUsec this is used for send timeouts.
+   *
+   * @var int
+   */
+  private $sendTimeoutSec_ = 0;
+
+  /**
+   * Send timeout in microseconds.
+   *
+   * Combined with sendTimeoutSec this is used for send timeouts.
+   *
+   * @var int
+   */
+  private $sendTimeoutUsec_ = 100000;
+
+  /**
+   * Recv timeout in seconds
+   *
+   * Combined with recvTimeoutUsec this is used for recv timeouts.
+   *
+   * @var int
+   */
+  private $recvTimeoutSec_ = 0;
+
+  /**
+   * Recv timeout in microseconds
+   *
+   * Combined with recvTimeoutSec this is used for recv timeouts.
+   *
+   * @var int
+   */
+  private $recvTimeoutUsec_ = 750000;
+
+  /**
+   * Persistent socket or plain?
+   *
+   * @var bool
+   */
+  protected $persist_ = FALSE;
+
+  /**
+   * Debugging on?
+   *
+   * @var bool
+   */
+  protected $debug_ = FALSE;
+
+  /**
+   * Debug handler
+   *
+   * @var mixed
+   */
+  protected $debugHandler_ = null;
+
+  /**
+   * Socket constructor
+   *
+   * @param string $host         Remote hostname
+   * @param int    $port         Remote port
+   * @param bool   $persist      Whether to use a persistent socket
+   * @param string $debugHandler Function to call for error logging
+   */
+  public function __construct($host='localhost',
+                              $port=9090,
+                              $persist=FALSE,
+                              $debugHandler=null) {
+    $this->host_ = $host;
+    $this->port_ = $port;
+    $this->persist_ = $persist;
+    $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
+  }
+
+  /**
+   * @param resource $handle
+   * @return void
+   */
+  public function setHandle($handle) {
+    $this->handle_ = $handle;
+  }
+
+  /**
+   * Sets the send timeout.
+   *
+   * @param int $timeout  Timeout in milliseconds.
+   */
+  public function setSendTimeout($timeout) {
+    $this->sendTimeoutSec_ = floor($timeout / 1000);
+    $this->sendTimeoutUsec_ =
+            ($timeout - ($this->sendTimeoutSec_ * 1000)) * 1000;
+  }
+
+  /**
+   * Sets the receive timeout.
+   *
+   * @param int $timeout  Timeout in milliseconds.
+   */
+  public function setRecvTimeout($timeout) {
+    $this->recvTimeoutSec_ = floor($timeout / 1000);
+    $this->recvTimeoutUsec_ =
+            ($timeout - ($this->recvTimeoutSec_ * 1000)) * 1000;
+  }
+
+  /**
+   * Sets debugging output on or off
+   *
+   * @param bool $debug
+   */
+  public function setDebug($debug) {
+    $this->debug_ = $debug;
+  }
+
+  /**
+   * Get the host that this socket is connected to
+   *
+   * @return string host
+   */
+  public function getHost() {
+    return $this->host_;
+  }
+
+  /**
+   * Get the remote port that this socket is connected to
+   *
+   * @return int port
+   */
+  public function getPort() {
+    return $this->port_;
+  }
+
+  /**
+   * Tests whether this is open
+   *
+   * @return bool true if the socket is open
+   */
+  public function isOpen() {
+    return is_resource($this->handle_);
+  }
+
+  /**
+   * Connects the socket.
+   */
+  public function open() {
+    if ($this->isOpen()) {
+      throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN);
+    }
+
+    if (empty($this->host_)) {
+      throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN);
+    }
+
+    if ($this->port_ <= 0) {
+      throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN);
+    }
+
+    if ($this->persist_) {
+      $this->handle_ = @pfsockopen($this->host_,
+                                   $this->port_,
+                                   $errno,
+                                   $errstr,
+                                   $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
+    } else {
+      $this->handle_ = @fsockopen($this->host_,
+                                  $this->port_,
+                                  $errno,
+                                  $errstr,
+                                  $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
+    }
+
+    // Connect failed?
+    if ($this->handle_ === FALSE) {
+      $error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
+      if ($this->debug_) {
+        call_user_func($this->debugHandler_, $error);
+      }
+      throw new TException($error);
+    }
+  }
+
+  /**
+   * Closes the socket.
+   */
+  public function close() {
+    if (!$this->persist_) {
+      @fclose($this->handle_);
+      $this->handle_ = null;
+    }
+  }
+
+  /**
+   * Read from the socket at most $len bytes.
+   *
+   * This method will not wait for all the requested data, it will return as
+   * soon as any data is received.
+   *
+   * @param int $len Maximum number of bytes to read.
+   * @return string Binary data
+   */
+  public function read($len) {
+    $null = null;
+    $read = array($this->handle_);
+    $readable = @stream_select($read, $null, $null, $this->recvTimeoutSec_, $this->recvTimeoutUsec_);
+
+    if ($readable > 0) {
+      $data = @stream_socket_recvfrom($this->handle_, $len);
+      if ($data === false) {
+          throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
+                               $this->host_.':'.$this->port_);
+      } elseif($data == '' && feof($this->handle_)) {
+          throw new TTransportException('TSocket read 0 bytes');
+        }
+
+      return $data;
+    } else if ($readable === 0) {
+        throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '.
+                             $this->host_.':'.$this->port_);
+      } else {
+        throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
+                             $this->host_.':'.$this->port_);
+      }
+    }
+
+  /**
+   * Write to the socket.
+   *
+   * @param string $buf The data to write
+   */
+  public function write($buf) {
+    $null = null;
+    $write = array($this->handle_);
+
+    // keep writing until all the data has been written
+    while (TStringFuncFactory::create()->strlen($buf) > 0) {
+      // wait for stream to become available for writing
+      $writable = @stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
+      if ($writable > 0) {
+        // write buffer to stream
+        $written = @stream_socket_sendto($this->handle_, $buf);
+        if ($written === -1 || $written === false) {
+          throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
+                                   $this->host_.':'.$this->port_);
+        }
+        // determine how much of the buffer is left to write
+        $buf = TStringFuncFactory::create()->substr($buf, $written);
+      } else if ($writable === 0) {
+          throw new TTransportException('TSocket: timed out writing '.TStringFuncFactory::create()->strlen($buf).' bytes from '.
+                               $this->host_.':'.$this->port_);
+        } else {
+            throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
+                                 $this->host_.':'.$this->port_);
+        }
+      }
+    }
+
+  /**
+   * Flush output to the socket.
+   *
+   * Since read(), readAll() and write() operate on the sockets directly,
+   * this is a no-op
+   *
+   * If you wish to have flushable buffering behaviour, wrap this TSocket
+   * in a TBufferedTransport.
+   */
+  public function flush() {
+    // no-op
+    }
+  }
diff --git a/lib/php/lib/Thrift/Transport/TSocketPool.php b/lib/php/lib/Thrift/Transport/TSocketPool.php
new file mode 100644
index 0000000..e1610cb
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TSocketPool.php
@@ -0,0 +1,295 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Transport\TSocket;
+use Thrift\Exception\TException;
+
+/**
+ * This library makes use of APC cache to make hosts as down in a web
+ * environment. If you are running from the CLI or on a system without APC
+ * installed, then these null functions will step in and act like cache
+ * misses.
+ */
+if (!function_exists('apc_fetch')) {
+  function apc_fetch($key) { return FALSE; }
+  function apc_store($key, $var, $ttl=0) { return FALSE; }
+}
+
+/**
+ * Sockets implementation of the TTransport interface that allows connection
+ * to a pool of servers.
+ *
+ * @package thrift.transport
+ */
+class TSocketPool extends TSocket {
+
+  /**
+   * Remote servers. Array of associative arrays with 'host' and 'port' keys
+   */
+  private $servers_ = array();
+
+  /**
+   * How many times to retry each host in connect
+   *
+   * @var int
+   */
+  private $numRetries_ = 1;
+
+  /**
+   * Retry interval in seconds, how long to not try a host if it has been
+   * marked as down.
+   *
+   * @var int
+   */
+  private $retryInterval_ = 60;
+
+  /**
+   * Max consecutive failures before marking a host down.
+   *
+   * @var int
+   */
+  private $maxConsecutiveFailures_ = 1;
+
+  /**
+   * Try hosts in order? or Randomized?
+   *
+   * @var bool
+   */
+  private $randomize_ = TRUE;
+
+  /**
+   * Always try last host, even if marked down?
+   *
+   * @var bool
+   */
+  private $alwaysTryLast_ = TRUE;
+
+  /**
+   * Socket pool constructor
+   *
+   * @param array  $hosts        List of remote hostnames
+   * @param mixed  $ports        Array of remote ports, or a single common port
+   * @param bool   $persist      Whether to use a persistent socket
+   * @param mixed  $debugHandler Function for error logging
+   */
+  public function __construct($hosts=array('localhost'),
+                              $ports=array(9090),
+                              $persist=FALSE,
+                              $debugHandler=null) {
+    parent::__construct(null, 0, $persist, $debugHandler);
+
+    if (!is_array($ports)) {
+      $port = $ports;
+      $ports = array();
+      foreach ($hosts as $key => $val) {
+        $ports[$key] = $port;
+      }
+    }
+
+    foreach ($hosts as $key => $host) {
+      $this->servers_ []= array('host' => $host,
+                                'port' => $ports[$key]);
+    }
+  }
+
+  /**
+   * Add a server to the pool
+   *
+   * This function does not prevent you from adding a duplicate server entry.
+   *
+   * @param string $host hostname or IP
+   * @param int $port port
+   */
+  public function addServer($host, $port) {
+    $this->servers_[] = array('host' => $host, 'port' => $port);
+  }
+
+  /**
+   * Sets how many time to keep retrying a host in the connect function.
+   *
+   * @param int $numRetries
+   */
+  public function setNumRetries($numRetries) {
+    $this->numRetries_ = $numRetries;
+  }
+
+  /**
+   * Sets how long to wait until retrying a host if it was marked down
+   *
+   * @param int $numRetries
+   */
+  public function setRetryInterval($retryInterval) {
+    $this->retryInterval_ = $retryInterval;
+  }
+
+  /**
+   * Sets how many time to keep retrying a host before marking it as down.
+   *
+   * @param int $numRetries
+   */
+  public function setMaxConsecutiveFailures($maxConsecutiveFailures) {
+    $this->maxConsecutiveFailures_ = $maxConsecutiveFailures;
+  }
+
+  /**
+   * Turns randomization in connect order on or off.
+   *
+   * @param bool $randomize
+   */
+  public function setRandomize($randomize) {
+    $this->randomize_ = $randomize;
+  }
+
+  /**
+   * Whether to always try the last server.
+   *
+   * @param bool $alwaysTryLast
+   */
+  public function setAlwaysTryLast($alwaysTryLast) {
+    $this->alwaysTryLast_ = $alwaysTryLast;
+  }
+
+
+  /**
+   * Connects the socket by iterating through all the servers in the pool
+   * and trying to find one that works.
+   */
+  public function open() {
+    // Check if we want order randomization
+    if ($this->randomize_) {
+      shuffle($this->servers_);
+    }
+
+    // Count servers to identify the "last" one
+    $numServers = count($this->servers_);
+
+    for ($i = 0; $i < $numServers; ++$i) {
+
+      // This extracts the $host and $port variables
+      extract($this->servers_[$i]);
+
+      // Check APC cache for a record of this server being down
+      $failtimeKey = 'thrift_failtime:'.$host.':'.$port.'~';
+
+      // Cache miss? Assume it's OK
+      $lastFailtime = apc_fetch($failtimeKey);
+      if ($lastFailtime === FALSE) {
+        $lastFailtime = 0;
+      }
+
+      $retryIntervalPassed = FALSE;
+
+      // Cache hit...make sure enough the retry interval has elapsed
+      if ($lastFailtime > 0) {
+        $elapsed = time() - $lastFailtime;
+        if ($elapsed > $this->retryInterval_) {
+          $retryIntervalPassed = TRUE;
+          if ($this->debug_) {
+            call_user_func($this->debugHandler_,
+                           'TSocketPool: retryInterval '.
+                           '('.$this->retryInterval_.') '.
+                           'has passed for host '.$host.':'.$port);
+          }
+        }
+      }
+
+      // Only connect if not in the middle of a fail interval, OR if this
+      // is the LAST server we are trying, just hammer away on it
+      $isLastServer = FALSE;
+      if ($this->alwaysTryLast_) {
+        $isLastServer = ($i == ($numServers - 1));
+      }
+
+      if (($lastFailtime === 0) ||
+          ($isLastServer) ||
+          ($lastFailtime > 0 && $retryIntervalPassed)) {
+
+        // Set underlying TSocket params to this one
+        $this->host_ = $host;
+        $this->port_ = $port;
+
+        // Try up to numRetries_ connections per server
+        for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) {
+          try {
+            // Use the underlying TSocket open function
+            parent::open();
+
+            // Only clear the failure counts if required to do so
+            if ($lastFailtime > 0) {
+              apc_store($failtimeKey, 0);
+            }
+
+            // Successful connection, return now
+            return;
+
+          } catch (TException $tx) {
+            // Connection failed
+          }
+        }
+
+        // Mark failure of this host in the cache
+        $consecfailsKey = 'thrift_consecfails:'.$host.':'.$port.'~';
+
+        // Ignore cache misses
+        $consecfails = apc_fetch($consecfailsKey);
+        if ($consecfails === FALSE) {
+          $consecfails = 0;
+        }
+
+        // Increment by one
+        $consecfails++;
+
+        // Log and cache this failure
+        if ($consecfails >= $this->maxConsecutiveFailures_) {
+          if ($this->debug_) {
+            call_user_func($this->debugHandler_,
+                           'TSocketPool: marking '.$host.':'.$port.
+                           ' as down for '.$this->retryInterval_.' secs '.
+                           'after '.$consecfails.' failed attempts.');
+          }
+          // Store the failure time
+          apc_store($failtimeKey, time());
+
+          // Clear the count of consecutive failures
+          apc_store($consecfailsKey, 0);
+        } else {
+          apc_store($consecfailsKey, $consecfails);
+        }
+      }
+    }
+
+    // Oh no; we failed them all. The system is totally ill!
+    $error = 'TSocketPool: All hosts in pool are down. ';
+    $hosts = array();
+    foreach ($this->servers_ as $server) {
+      $hosts []= $server['host'].':'.$server['port'];
+    }
+    $hostlist = implode(',', $hosts);
+    $error .= '('.$hostlist.')';
+    if ($this->debug_) {
+      call_user_func($this->debugHandler_, $error);
+    }
+    throw new TException($error);
+  }
+}
diff --git a/lib/php/lib/Thrift/Transport/TTransport.php b/lib/php/lib/Thrift/Transport/TTransport.php
new file mode 100644
index 0000000..2e44366
--- /dev/null
+++ b/lib/php/lib/Thrift/Transport/TTransport.php
@@ -0,0 +1,93 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Transport;
+
+use Thrift\Factory\TStringFuncFactory;
+
+/**
+ * Base interface for a transport agent.
+ *
+ * @package thrift.transport
+ */
+abstract class TTransport {
+
+  /**
+   * Whether this transport is open.
+   *
+   * @return boolean true if open
+   */
+  public abstract function isOpen();
+
+  /**
+   * Open the transport for reading/writing
+   *
+   * @throws TTransportException if cannot open
+   */
+  public abstract function open();
+
+  /**
+   * Close the transport.
+   */
+  public abstract function close();
+
+  /**
+   * Read some data into the array.
+   *
+   * @param int    $len How much to read
+   * @return string The data that has been read
+   * @throws TTransportException if cannot read any more data
+   */
+  public abstract function read($len);
+
+  /**
+   * Guarantees that the full amount of data is read.
+   *
+   * @return string The data, of exact length
+   * @throws TTransportException if cannot read data
+   */
+  public function readAll($len) {
+    // return $this->read($len);
+
+    $data = '';
+    $got = 0;
+    while (($got = TStringFuncFactory::create()->strlen($data)) < $len) {
+      $data .= $this->read($len - $got);
+    }
+    return $data;
+  }
+
+  /**
+   * Writes the given data out.
+   *
+   * @param string $buf  The data to write
+   * @throws TTransportException if writing fails
+   */
+  public abstract function write($buf);
+
+  /**
+   * Flushes any pending data out of a buffer
+   *
+   * @throws TTransportException if a writing error occurs
+   */
+  public function flush() {}
+}
diff --git a/lib/php/lib/Thrift/Type/TMessageType.php b/lib/php/lib/Thrift/Type/TMessageType.php
new file mode 100644
index 0000000..681c45c
--- /dev/null
+++ b/lib/php/lib/Thrift/Type/TMessageType.php
@@ -0,0 +1,33 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Type;
+
+/**
+ * Message types for RPC
+ */
+class TMessageType {
+  const CALL  = 1;
+  const REPLY = 2;
+  const EXCEPTION = 3;
+  const ONEWAY = 4;
+}
\ No newline at end of file
diff --git a/lib/php/lib/Thrift/Type/TType.php b/lib/php/lib/Thrift/Type/TType.php
new file mode 100644
index 0000000..c1cf228
--- /dev/null
+++ b/lib/php/lib/Thrift/Type/TType.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * 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.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Type;
+
+/**
+ * Data types that can be sent via Thrift
+ */
+class TType {
+  const STOP   = 0;
+  const VOID   = 1;
+  const BOOL   = 2;
+  const BYTE   = 3;
+  const I08    = 3;
+  const DOUBLE = 4;
+  const I16    = 6;
+  const I32    = 8;
+  const I64    = 10;
+  const STRING = 11;
+  const UTF7   = 11;
+  const STRUCT = 12;
+  const MAP    = 13;
+  const SET    = 14;
+  const LST    = 15;    // N.B. cannot use LIST keyword in PHP!
+  const UTF8   = 16;
+  const UTF16  = 17;
+}
diff --git a/lib/php/src/protocol/TBinaryProtocol.php b/lib/php/src/protocol/TBinaryProtocol.php
index 40b9f9b..e69de29 100644
--- a/lib/php/src/protocol/TBinaryProtocol.php
+++ b/lib/php/src/protocol/TBinaryProtocol.php
@@ -1,429 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.protocol
- */
-
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
-
-/**
- * Binary implementation of the Thrift protocol.
- *
- */
-class TBinaryProtocol extends TProtocol {
-
-  const VERSION_MASK = 0xffff0000;
-  const VERSION_1 = 0x80010000;
-
-  protected $strictRead_ = false;
-  protected $strictWrite_ = true;
-
-  public function __construct($trans, $strictRead=false, $strictWrite=true) {
-    parent::__construct($trans);
-    $this->strictRead_ = $strictRead;
-    $this->strictWrite_ = $strictWrite;
-  }
-
-  public function writeMessageBegin($name, $type, $seqid) {
-    if ($this->strictWrite_) {
-      $version = self::VERSION_1 | $type;
-      return
-        $this->writeI32($version) +
-        $this->writeString($name) +
-        $this->writeI32($seqid);
-    } else {
-      return
-        $this->writeString($name) +
-        $this->writeByte($type) +
-        $this->writeI32($seqid);
-    }
-  }
-
-  public function writeMessageEnd() {
-    return 0;
-  }
-
-  public function writeStructBegin($name) {
-    return 0;
-  }
-
-  public function writeStructEnd() {
-    return 0;
-  }
-
-  public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
-    return
-      $this->writeByte($fieldType) +
-      $this->writeI16($fieldId);
-  }
-
-  public function writeFieldEnd() {
-    return 0;
-  }
-
-  public function writeFieldStop() {
-    return
-      $this->writeByte(TType::STOP);
-  }
-
-  public function writeMapBegin($keyType, $valType, $size) {
-    return
-      $this->writeByte($keyType) +
-      $this->writeByte($valType) +
-      $this->writeI32($size);
-  }
-
-  public function writeMapEnd() {
-    return 0;
-  }
-
-  public function writeListBegin($elemType, $size) {
-    return
-      $this->writeByte($elemType) +
-      $this->writeI32($size);
-  }
-
-  public function writeListEnd() {
-    return 0;
-  }
-
-  public function writeSetBegin($elemType, $size) {
-    return
-      $this->writeByte($elemType) +
-      $this->writeI32($size);
-  }
-
-  public function writeSetEnd() {
-    return 0;
-  }
-
-  public function writeBool($value) {
-    $data = pack('c', $value ? 1 : 0);
-    $this->trans_->write($data, 1);
-    return 1;
-  }
-
-  public function writeByte($value) {
-    $data = pack('c', $value);
-    $this->trans_->write($data, 1);
-    return 1;
-  }
-
-  public function writeI16($value) {
-    $data = pack('n', $value);
-    $this->trans_->write($data, 2);
-    return 2;
-  }
-
-  public function writeI32($value) {
-    $data = pack('N', $value);
-    $this->trans_->write($data, 4);
-    return 4;
-  }
-
-  public function writeI64($value) {
-    // If we are on a 32bit architecture we have to explicitly deal with
-    // 64-bit twos-complement arithmetic since PHP wants to treat all ints
-    // as signed and any int over 2^31 - 1 as a float
-    if (PHP_INT_SIZE == 4) {
-      $neg = $value < 0;
-
-      if ($neg) {
-        $value *= -1;
-      }
-
-      $hi = (int)($value / 4294967296);
-      $lo = (int)$value;
-
-      if ($neg) {
-        $hi = ~$hi;
-        $lo = ~$lo;
-        if (($lo & (int)0xffffffff) == (int)0xffffffff) {
-          $lo = 0;
-          $hi++;
-        } else {
-          $lo++;
-        }
-      }
-      $data = pack('N2', $hi, $lo);
-
-    } else {
-      $hi = $value >> 32;
-      $lo = $value & 0xFFFFFFFF;
-      $data = pack('N2', $hi, $lo);
-    }
-
-    $this->trans_->write($data, 8);
-    return 8;
-  }
-
-  public function writeDouble($value) {
-    $data = pack('d', $value);
-    $this->trans_->write(strrev($data), 8);
-    return 8;
-  }
-
-  public function writeString($value) {
-    $len = TStringFuncFactory::create()->strlen($value);
-    $result = $this->writeI32($len);
-    if ($len) {
-      $this->trans_->write($value, $len);
-    }
-    return $result + $len;
-  }
-
-  public function readMessageBegin(&$name, &$type, &$seqid) {
-    $result = $this->readI32($sz);
-    if ($sz < 0) {
-      $version = (int) ($sz & self::VERSION_MASK);
-      if ($version != (int) self::VERSION_1) {
-        throw new TProtocolException('Bad version identifier: '.$sz, TProtocolException::BAD_VERSION);
-      }
-      $type = $sz & 0x000000ff;
-      $result +=
-        $this->readString($name) +
-        $this->readI32($seqid);
-    } else {
-      if ($this->strictRead_) {
-        throw new TProtocolException('No version identifier, old protocol client?', TProtocolException::BAD_VERSION);
-      } else {
-        // Handle pre-versioned input
-        $name = $this->trans_->readAll($sz);
-        $result +=
-          $sz +
-          $this->readByte($type) +
-          $this->readI32($seqid);
-      }
-    }
-    return $result;
-  }
-
-  public function readMessageEnd() {
-    return 0;
-  }
-
-  public function readStructBegin(&$name) {
-    $name = '';
-    return 0;
-  }
-
-  public function readStructEnd() {
-    return 0;
-  }
-
-  public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
-    $result = $this->readByte($fieldType);
-    if ($fieldType == TType::STOP) {
-      $fieldId = 0;
-      return $result;
-    }
-    $result += $this->readI16($fieldId);
-    return $result;
-  }
-
-  public function readFieldEnd() {
-    return 0;
-  }
-
-  public function readMapBegin(&$keyType, &$valType, &$size) {
-    return
-      $this->readByte($keyType) +
-      $this->readByte($valType) +
-      $this->readI32($size);
-  }
-
-  public function readMapEnd() {
-    return 0;
-  }
-
-  public function readListBegin(&$elemType, &$size) {
-    return
-      $this->readByte($elemType) +
-      $this->readI32($size);
-  }
-
-  public function readListEnd() {
-    return 0;
-  }
-
-  public function readSetBegin(&$elemType, &$size) {
-    return
-      $this->readByte($elemType) +
-      $this->readI32($size);
-  }
-
-  public function readSetEnd() {
-    return 0;
-  }
-
-  public function readBool(&$value) {
-    $data = $this->trans_->readAll(1);
-    $arr = unpack('c', $data);
-    $value = $arr[1] == 1;
-    return 1;
-  }
-
-  public function readByte(&$value) {
-    $data = $this->trans_->readAll(1);
-    $arr = unpack('c', $data);
-    $value = $arr[1];
-    return 1;
-  }
-
-  public function readI16(&$value) {
-    $data = $this->trans_->readAll(2);
-    $arr = unpack('n', $data);
-    $value = $arr[1];
-    if ($value > 0x7fff) {
-      $value = 0 - (($value - 1) ^ 0xffff);
-    }
-    return 2;
-  }
-
-  public function readI32(&$value) {
-    $data = $this->trans_->readAll(4);
-    $arr = unpack('N', $data);
-    $value = $arr[1];
-    if ($value > 0x7fffffff) {
-      $value = 0 - (($value - 1) ^ 0xffffffff);
-    }
-    return 4;
-  }
-
-  public function readI64(&$value) {
-    $data = $this->trans_->readAll(8);
-
-    $arr = unpack('N2', $data);
-
-    // If we are on a 32bit architecture we have to explicitly deal with
-    // 64-bit twos-complement arithmetic since PHP wants to treat all ints
-    // as signed and any int over 2^31 - 1 as a float
-    if (PHP_INT_SIZE == 4) {
-
-      $hi = $arr[1];
-      $lo = $arr[2];
-      $isNeg = $hi  < 0;
-
-      // Check for a negative
-      if ($isNeg) {
-        $hi = ~$hi & (int)0xffffffff;
-        $lo = ~$lo & (int)0xffffffff;
-
-        if ($lo == (int)0xffffffff) {
-          $hi++;
-          $lo = 0;
-        } else {
-          $lo++;
-        }
-      }
-
-      // Force 32bit words in excess of 2G to pe positive - we deal wigh sign
-      // explicitly below
-
-      if ($hi & (int)0x80000000) {
-        $hi &= (int)0x7fffffff;
-        $hi += 0x80000000;
-      }
-
-      if ($lo & (int)0x80000000) {
-        $lo &= (int)0x7fffffff;
-        $lo += 0x80000000;
-      }
-
-      $value = $hi * 4294967296 + $lo;
-
-      if ($isNeg) {
-        $value = 0 - $value;
-      }
-    } else {
-
-      // Upcast negatives in LSB bit
-      if ($arr[2] & 0x80000000) {
-        $arr[2] = $arr[2] & 0xffffffff;
-      }
-
-      // Check for a negative
-      if ($arr[1] & 0x80000000) {
-        $arr[1] = $arr[1] & 0xffffffff;
-        $arr[1] = $arr[1] ^ 0xffffffff;
-        $arr[2] = $arr[2] ^ 0xffffffff;
-        $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
-      } else {
-        $value = $arr[1]*4294967296 + $arr[2];
-      }
-    }
-
-    return 8;
-  }
-
-  public function readDouble(&$value) {
-    $data = strrev($this->trans_->readAll(8));
-    $arr = unpack('d', $data);
-    $value = $arr[1];
-    return 8;
-  }
-
-  public function readString(&$value) {
-    $result = $this->readI32($len);
-    if ($len) {
-      $value = $this->trans_->readAll($len);
-    } else {
-      $value = '';
-    }
-    return $result + $len;
-  }
-}
-
-/**
- * Binary Protocol Factory
- */
-class TBinaryProtocolFactory implements TProtocolFactory {
-  private $strictRead_ = false;
-  private $strictWrite_ = false;
-
-  public function __construct($strictRead=false, $strictWrite=false) {
-    $this->strictRead_ = $strictRead;
-    $this->strictWrite_ = $strictWrite;
-  }
-
-  public function getProtocol($trans) {
-    return new TBinaryProtocol($trans, $this->strictRead_, $this->strictWrite_);
-  }
-}
-
-/**
- * Accelerated binary protocol: used in conjunction with the thrift_protocol
- * extension for faster deserialization
- */
-class TBinaryProtocolAccelerated extends TBinaryProtocol {
-  public function __construct($trans, $strictRead=false, $strictWrite=true) {
-    // If the transport doesn't implement putBack, wrap it in a
-    // TBufferedTransport (which does)
-    if (!method_exists($trans, 'putBack')) {
-      $trans = new TBufferedTransport($trans);
-    }
-    parent::__construct($trans, $strictRead, $strictWrite);
-  }
-  public function isStrictRead() {
-    return $this->strictRead_;
-  }
-  public function isStrictWrite() {
-    return $this->strictWrite_;
-  }
-}
diff --git a/lib/php/src/protocol/TBinarySerializer.php b/lib/php/src/protocol/TBinarySerializer.php
index 542233b..e69de29 100644
--- a/lib/php/src/protocol/TBinarySerializer.php
+++ b/lib/php/src/protocol/TBinarySerializer.php
@@ -1,70 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.protocol
- * @author: rmarin (marin.radu@facebook.com)
- */
-
-require_once $GLOBALS['THRIFT_ROOT'].'/transport/TMemoryBuffer.php';
-require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
-
-/**
- * Utility class for serializing and deserializing
- * a thrift object using TBinaryProtocolAccelerated.
- */
-class TBinarySerializer {
-
-  // NOTE(rmarin): Because thrift_protocol_write_binary
-  // adds a begin message prefix, you cannot specify
-  // a transport in which to serialize an object. It has to
-  // be a string. Otherwise we will break the compatibility with
-  // normal deserialization.
-  public static function serialize($object) {
-    $transport = new TMemoryBuffer();
-    $protocol = new TBinaryProtocolAccelerated($transport);
-    if (function_exists('thrift_protocol_write_binary')) {
-      thrift_protocol_write_binary($protocol, $object->getName(),
-                                   TMessageType::REPLY, $object,
-                                   0, $protocol->isStrictWrite());
-
-      $protocol->readMessageBegin($unused_name, $unused_type,
-                                  $unused_seqid);
-    } else {
-      $object->write($protocol);
-    }
-    $protocol->getTransport()->flush();
-    return $transport->getBuffer();
-  }
-
-  public static function deserialize($string_object, $class_name) {
-     $transport = new TMemoryBuffer();
-     $protocol = new TBinaryProtocolAccelerated($transport);
-     if (function_exists('thrift_protocol_read_binary')) {
-       $protocol->writeMessageBegin('', TMessageType::REPLY, 0);
-       $transport->write($string_object);
-       return thrift_protocol_read_binary($protocol, $class_name,
-                                          $protocol->isStrictRead());
-     } else {
-       $transport->write($string_object);
-       $object = new $class_name();
-       $object->read($protocol);
-       return $object;
-     }
-  }
-}
diff --git a/lib/php/src/protocol/TCompactProtocol.php b/lib/php/src/protocol/TCompactProtocol.php
index 9f0d407..e69de29 100644
--- a/lib/php/src/protocol/TCompactProtocol.php
+++ b/lib/php/src/protocol/TCompactProtocol.php
@@ -1,678 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.protocol
- */
-
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
-
-/**
- * Compact implementation of the Thrift protocol.
- *
- */
-class TCompactProtocol extends TProtocol {
-
-  const COMPACT_STOP = 0x00;
-  const COMPACT_TRUE = 0x01;
-  const COMPACT_FALSE = 0x02;
-  const COMPACT_BYTE = 0x03;
-  const COMPACT_I16 = 0x04;
-  const COMPACT_I32 = 0x05;
-  const COMPACT_I64 = 0x06;
-  const COMPACT_DOUBLE = 0x07;
-  const COMPACT_BINARY = 0x08;
-  const COMPACT_LIST = 0x09;
-  const COMPACT_SET = 0x0A;
-  const COMPACT_MAP = 0x0B;
-  const COMPACT_STRUCT = 0x0C;
-
-  const STATE_CLEAR = 0;
-  const STATE_FIELD_WRITE = 1;
-  const STATE_VALUE_WRITE = 2;
-  const STATE_CONTAINER_WRITE = 3;
-  const STATE_BOOL_WRITE = 4;
-  const STATE_FIELD_READ = 5;
-  const STATE_CONTAINER_READ = 6;
-  const STATE_VALUE_READ = 7;
-  const STATE_BOOL_READ = 8;
-
-  const VERSION_MASK = 0x1f;
-  const VERSION = 1;
-  const PROTOCOL_ID = 0x82;
-  const TYPE_MASK = 0xe0;
-  const TYPE_SHIFT_AMOUNT = 5;
-
-  protected static $ctypes = array(
-    TType::STOP => TCompactProtocol::COMPACT_STOP,
-    TType::BOOL => TCompactProtocol::COMPACT_TRUE, // used for collection
-    TType::BYTE => TCompactProtocol::COMPACT_BYTE,
-    TType::I16 => TCompactProtocol::COMPACT_I16,
-    TType::I32 => TCompactProtocol::COMPACT_I32,
-    TType::I64 => TCompactProtocol::COMPACT_I64,
-    TType::DOUBLE => TCompactProtocol::COMPACT_DOUBLE,
-    TType::STRING => TCompactProtocol::COMPACT_BINARY,
-    TType::STRUCT => TCompactProtocol::COMPACT_STRUCT,
-    TType::LST => TCompactProtocol::COMPACT_LIST,
-    TType::SET => TCompactProtocol::COMPACT_SET,
-    TType::MAP => TCompactProtocol::COMPACT_MAP,
-  );
-
-  protected static $ttypes = array(
-    TCompactProtocol::COMPACT_STOP => TType::STOP ,
-    TCompactProtocol::COMPACT_TRUE => TType::BOOL, // used for collection
-    TCompactProtocol::COMPACT_FALSE => TType::BOOL,
-    TCompactProtocol::COMPACT_BYTE => TType::BYTE,
-    TCompactProtocol::COMPACT_I16 => TType::I16,
-    TCompactProtocol::COMPACT_I32 => TType::I32,
-    TCompactProtocol::COMPACT_I64 => TType::I64,
-    TCompactProtocol::COMPACT_DOUBLE => TType::DOUBLE,
-    TCompactProtocol::COMPACT_BINARY => TType::STRING,
-    TCompactProtocol::COMPACT_STRUCT => TType::STRUCT,
-    TCompactProtocol::COMPACT_LIST => TType::LST,
-    TCompactProtocol::COMPACT_SET => TType::SET,
-    TCompactProtocol::COMPACT_MAP => TType::MAP,
-  );
-
-  protected $state = TCompactProtocol::STATE_CLEAR;
-  protected $lastFid = 0;
-  protected $boolFid = null;
-  protected $boolValue = null;
-  protected $structs = array();
-  protected $containers = array();
-
-  // Some varint / zigzag helper methods
-  public function toZigZag($n, $bits) {
-    return ($n << 1) ^ ($n >> ($bits - 1));
-  }
-
-  public function fromZigZag($n) {
-    return ($n >> 1) ^ -($n & 1);
-  }
-
-  public function getVarint($data) {
-    $out = "";
-    while (true) {
-      if (($data & ~0x7f) === 0) {
-        $out .= chr($data);
-        break;
-      } else {
-        $out .= chr(($data & 0xff) | 0x80);
-        $data = $data >> 7;
-      }
-    }
-    return $out;
-  }
-
-  public function writeVarint($data) {
-    $out = $this->getVarint($data);
-    $result = TStringFuncFactory::create()->strlen($out);
-    $this->trans_->write($out, $result);
-    return $result;
-  }
-
-  public function readVarint(&$result) {
-    $idx = 0;
-    $shift = 0;
-    $result = 0;
-    while (true) {
-      $x = $this->trans_->readAll(1);
-      $arr = unpack('C', $x);
-      $byte = $arr[1];
-      $idx += 1;
-      $result |= ($byte & 0x7f) << $shift;
-      if (($byte >> 7) === 0) {
-        return $idx;
-      }
-      $shift += 7;
-    }
-
-    return $idx;
-  }
-
-  public function __construct($trans) {
-    parent::__construct($trans);
-  }
-
-  public function writeMessageBegin($name, $type, $seqid) {
-    $written =
-      $this->writeUByte(TCompactProtocol::PROTOCOL_ID) +
-      $this->writeUByte(TCompactProtocol::VERSION |
-                        ($type << TCompactProtocol::TYPE_SHIFT_AMOUNT)) +
-      $this->writeVarint($seqid) +
-      $this->writeString($name);
-    $this->state = TCompactProtocol::STATE_VALUE_WRITE;
-    return $written;
-  }
-
-  public function writeMessageEnd() {
-    $this->state = TCompactProtocol::STATE_CLEAR;
-    return 0;
-  }
-
-  public function writeStructBegin($name) {
-    $this->structs[] = array($this->state, $this->lastFid);
-    $this->state = TCompactProtocol::STATE_FIELD_WRITE;
-    $this->lastFid = 0;
-    return 0;
-  }
-
-  public function writeStructEnd() {
-    $old_values = array_pop($this->structs);
-    $this->state = $old_values[0];
-    $this->lastFid = $old_values[1];
-    return 0;
-  }
-
-  public function writeFieldStop() {
-    return $this->writeByte(0);
-  }
-
-  public function writeFieldHeader($type, $fid) {
-    $written = 0;
-    $delta = $fid - $this->lastFid;
-    if (0 < $delta && $delta <= 15) {
-      $written = $this->writeUByte(($delta << 4) | $type);
-    } else {
-      $written = $this->writeByte($type) +
-        $this->writeI16($fid);
-    }
-    $this->lastFid = $fid;
-    return $written;
-  }
-
-  public function writeFieldBegin($field_name, $field_type, $field_id) {
-    if ($field_type == TTYPE::BOOL) {
-      $this->state = TCompactProtocol::STATE_BOOL_WRITE;
-      $this->boolFid = $field_id;
-      return 0;
-    } else {
-      $this->state = TCompactProtocol::STATE_VALUE_WRITE;
-      return $this->writeFieldHeader(self::$ctypes[$field_type], $field_id);
-    }
-  }
-
-  public function writeFieldEnd() {
-    $this->state = TCompactProtocol::STATE_FIELD_WRITE;
-    return 0;
-  }
-
-  public function writeCollectionBegin($etype, $size) {
-    $written = 0;
-    if ($size <= 14) {
-      $written = $this->writeUByte($size << 4 |
-                                    self::$ctypes[$etype]);
-    } else {
-      $written = $this->writeUByte(0xf0 |
-                                   self::$ctypes[$etype]) +
-        $this->writeVarint($size);
-    }
-    $this->containers[] = $this->state;
-    $this->state = TCompactProtocol::STATE_CONTAINER_WRITE;
-
-    return $written;
-  }
-
-  public function writeMapBegin($key_type, $val_type, $size) {
-    $written = 0;
-    if ($size == 0) {
-      $written = $this->writeByte(0);
-    } else {
-      $written = $this->writeVarint($size) +
-        $this->writeUByte(self::$ctypes[$key_type] << 4 |
-                          self::$ctypes[$val_type]);
-    }
-    $this->containers[] = $this->state;
-    return $written;
-  }
-
-  public function writeCollectionEnd() {
-    $this->state = array_pop($this->containers);
-    return 0;
-  }
-
-  public function writeMapEnd() {
-    return $this->writeCollectionEnd();
-  }
-
-  public function writeListBegin($elem_type, $size) {
-    return $this->writeCollectionBegin($elem_type, $size);
-  }
-
-  public function writeListEnd() {
-    return $this->writeCollectionEnd();
-  }
-
-  public function writeSetBegin($elem_type, $size) {
-    return $this->writeCollectionBegin($elem_type, $size);
-  }
-
-  public function writeSetEnd() {
-    return $this->writeCollectionEnd();
-  }
-
-  public function writeBool($value) {
-    if ($this->state == TCompactProtocol::STATE_BOOL_WRITE) {
-      $ctype = TCompactProtocol::COMPACT_FALSE;
-      if ($value) {
-        $ctype = TCompactProtocol::COMPACT_TRUE;
-      }
-      return $this->writeFieldHeader($ctype, $this->boolFid);
-    } else if ($this->state == TCompactProtocol::STATE_CONTAINER_WRITE) {
-      return $this->writeByte($value ? 1 : 0);
-    } else {
-      throw new TProtocolException('Invalid state in compact protocol');
-    }
-  }
-
-  public function writeByte($value) {
-    $data = pack('c', $value);
-    $this->trans_->write($data, 1);
-    return 1;
-  }
-
-  public function writeUByte($byte) {
-    $this->trans_->write(pack('C', $byte), 1);
-    return 1;
-  }
-
-  public function writeI16($value) {
-    $thing = $this->toZigZag($value, 16);
-    return $this->writeVarint($thing);
-  }
-
-  public function writeI32($value) {
-    $thing = $this->toZigZag($value, 32);
-    return $this->writeVarint($thing);
-  }
-
-  public function writeDouble($value) {
-    $data = pack('d', $value);
-    $this->trans_->write(strrev($data), 8);
-    return 8;
-  }
-
-  public function writeString($value) {
-    $len = TStringFuncFactory::create()->strlen($value);
-    $result = $this->writeVarint($len);
-    if ($len) {
-      $this->trans_->write($value, $len);
-    }
-    return $result + $len;
-  }
-
-  public function readFieldBegin(&$name, &$field_type, &$field_id) {
-    $result = $this->readUByte($field_type);
-
-    if (($field_type & 0x0f) == TType::STOP) {
-      $field_id = 0;
-      return $result;
-    }
-    $delta = $field_type >> 4;
-    if ($delta == 0) {
-      $result += $this->readI16($field_id);
-    } else {
-      $field_id = $this->lastFid + $delta;
-    }
-    $this->lastFid = $field_id;
-    $field_type = $this->getTType($field_type & 0x0f);
-    if ($field_type == TCompactProtocol::COMPACT_TRUE) {
-      $this->state = TCompactProtocol::STATE_BOOL_READ;
-      $this->boolValue = true;
-    } else if ($field_type == TCompactProtocol::COMPACT_FALSE) {
-      $this->state = TCompactProtocol::STATE_BOOL_READ;
-      $this->boolValue = false;
-    } else {
-      $this->state = TCompactProtocol::STATE_VALUE_READ;
-    }
-    return $result;
-  }
-
-  public function readFieldEnd() {
-    $this->state = TCompactProtocol::STATE_FIELD_READ;
-    return 0;
-  }
-
-  public function readUByte(&$value) {
-    $data = $this->trans_->readAll(1);
-    $arr = unpack('C', $data);
-    $value = $arr[1];
-    return 1;
-  }
-
-  public function readByte(&$value) {
-    $data = $this->trans_->readAll(1);
-    $arr = unpack('c', $data);
-    $value = $arr[1];
-    return 1;
-  }
-
-  public function readZigZag(&$value) {
-    $result = $this->readVarint($value);
-    $value = $this->fromZigZag($value);
-    return $result;
-  }
-
-  public function readMessageBegin(&$name, &$type, &$seqid) {
-    $protoId = 0;
-    $result = $this->readUByte($protoId);
-    if ($protoId != TCompactProtocol::PROTOCOL_ID) {
-      throw new TProtocolException('Bad protocol id in TCompact message');
-    }
-    $verType = 0;
-    $result += $this->readUByte($verType);
-    $type = ($verType & TCompactProtocol::TYPE_MASK) >>
-      TCompactProtocol::TYPE_SHIFT_AMOUNT;
-    $version = $verType & TCompactProtocol::VERSION_MASK;
-    if ($version != TCompactProtocol::VERSION) {
-      throw new TProtocolException('Bad version in TCompact message');
-    }
-    $result += $this->readVarint($seqId);
-    $name += $this->readString($name);
-
-    return $result;
-  }
-
-  public function readMessageEnd() {
-    return 0;
-  }
-
-  public function readStructBegin(&$name) {
-    $name = ''; // unused
-    $this->structs[] = array($this->state, $this->lastFid);
-    $this->state = TCompactProtocol::STATE_FIELD_READ;
-    $this->lastFid = 0;
-    return 0;
-  }
-
-  public function readStructEnd() {
-    $last = array_pop($this->structs);
-    $this->state = $last[0];
-    $this->lastFid = $last[1];
-    return 0;
-  }
-
-  public function readCollectionBegin(&$type, &$size) {
-    $sizeType = 0;
-    $result = $this->readUByte($sizeType);
-    $size = $sizeType >> 4;
-    $type = $this->getTType($sizeType);
-    if ($size == 15) {
-      $result += $this->readVarint($size);
-    }
-    $this->containers[] = $this->state;
-    $this->state = TCompactProtocol::STATE_CONTAINER_READ;
-
-    return $result;
-  }
-
-  public function readMapBegin(&$key_type, &$val_type, &$size) {
-    $result = $this->readVarint($size);
-    $types = 0;
-    if ($size > 0) {
-      $result += $this->readUByte($types);
-    }
-    $val_type = $this->getTType($types);
-    $key_type = $this->getTType($types >> 4);
-    $this->containers[] = $this->state;
-    $this->state = TCompactProtocol::STATE_CONTAINER_READ;
-
-    return $result;
-  }
-
-  public function readCollectionEnd() {
-    $this->state = array_pop($this->containers);
-    return 0;
-  }
-
-  public function readMapEnd() {
-    return $this->readCollectionEnd();
-  }
-
-  public function readListBegin(&$elem_type, &$size) {
-    return $this->readCollectionBegin($elem_type, $size);
-  }
-
-  public function readListEnd() {
-    return $this->readCollectionEnd();
-  }
-
-  public function readSetBegin(&$elem_type, &$size) {
-    return $this->readCollectionBegin($elem_type, $size);
-  }
-
-  public function readSetEnd() {
-    return $this->readCollectionEnd();
-  }
-
-  public function readBool(&$value) {
-    if ($this->state == TCompactProtocol::STATE_BOOL_READ) {
-      $value = $this->boolValue;
-      return 0;
-    } else if ($this->state == TCompactProtocol::STATE_CONTAINER_READ) {
-      return $this->readByte($value);
-    } else {
-      throw new TProtocolException('Invalid state in compact protocol');
-    }
-  }
-
-  public function readI16(&$value) {
-    return $this->readZigZag($value);
-  }
-
-  public function readI32(&$value) {
-    return $this->readZigZag($value);
-  }
-
-  public function readDouble(&$value) {
-    $data = strrev($this->trans_->readAll(8));
-    $arr = unpack('d', $data);
-    $value = $arr[1];
-    return 8;
-  }
-
-  public function readString(&$value) {
-    $result = $this->readVarint($len);
-    if ($len) {
-      $value = $this->trans_->readAll($len);
-    } else {
-      $value = '';
-    }
-    return $result + $len;
-  }
-
-  public function getTType($byte) {
-    return self::$ttypes[$byte & 0x0f];
-  }
-
-  // If we are on a 32bit architecture we have to explicitly deal with
-  // 64-bit twos-complement arithmetic since PHP wants to treat all ints
-  // as signed and any int over 2^31 - 1 as a float
-
-  // Read and write I64 as two 32 bit numbers $hi and $lo
-
-  public function readI64(&$value) {
-    // Read varint from wire
-    $hi = 0;
-    $lo = 0;
-
-    $idx = 0;
-    $shift = 0;
-
-    while (true) {
-      $x = $this->trans_->readAll(1);
-      $arr = unpack('C', $x);
-      $byte = $arr[1];
-      $idx += 1;
-      if ($shift < 32) {
-        $lo |= (($byte & 0x7f) << $shift) &
-          0x00000000ffffffff;
-      }
-      // Shift hi and lo together.
-      if ($shift >= 32) {
-        $hi |= (($byte & 0x7f) << ($shift - 32));
-      } else if ($shift > 25) {
-        $hi |= (($byte & 0x7f) >> ($shift - 25));
-      }
-      if (($byte >> 7) === 0) {
-        break;
-      }
-      $shift += 7;
-    }
-
-    // Now, unzig it.
-    $xorer = 0;
-    if ($lo & 1) {
-      $xorer = 0xffffffff;
-    }
-    $lo = ($lo >> 1) & 0x7fffffff;
-    $lo = $lo | (($hi & 1) << 31);
-    $hi = ($hi >> 1) ^ $xorer;
-    $lo = $lo ^ $xorer;
-
-    // Now put $hi and $lo back together
-    if (true) {
-      $isNeg = $hi  < 0;
-
-      // Check for a negative
-      if ($isNeg) {
-        $hi = ~$hi & (int)0xffffffff;
-        $lo = ~$lo & (int)0xffffffff;
-
-        if ($lo == (int)0xffffffff) {
-          $hi++;
-          $lo = 0;
-        } else {
-          $lo++;
-        }
-      }
-
-      // Force 32bit words in excess of 2G to be positive - we deal with sign
-      // explicitly below
-
-      if ($hi & (int)0x80000000) {
-        $hi &= (int)0x7fffffff;
-        $hi += 0x80000000;
-      }
-
-      if ($lo & (int)0x80000000) {
-        $lo &= (int)0x7fffffff;
-        $lo += 0x80000000;
-      }
-
-      $value = $hi * 4294967296 + $lo;
-
-      if ($isNeg) {
-        $value = 0 - $value;
-      }
-    } else {
-
-      // Upcast negatives in LSB bit
-      if ($arr[2] & 0x80000000) {
-        $arr[2] = $arr[2] & 0xffffffff;
-      }
-
-      // Check for a negative
-      if ($arr[1] & 0x80000000) {
-        $arr[1] = $arr[1] & 0xffffffff;
-        $arr[1] = $arr[1] ^ 0xffffffff;
-        $arr[2] = $arr[2] ^ 0xffffffff;
-        $value = 0 - $arr[1] * 4294967296 - $arr[2] - 1;
-      } else {
-        $value = $arr[1] * 4294967296 + $arr[2];
-      }
-    }
-
-    return $idx;
-  }
-
-  public function writeI64($value) {
-    // If we are in an I32 range, use the easy method below.
-    if (($value > 4294967296) || ($value < -4294967296)) {
-      // Convert $value to $hi and $lo
-      $neg = $value < 0;
-
-      if ($neg) {
-        $value *= -1;
-      }
-
-      $hi = (int)$value >> 32;
-      $lo = (int)$value & 0xffffffff;
-
-      if ($neg) {
-        $hi = ~$hi;
-        $lo = ~$lo;
-        if (($lo & (int)0xffffffff) == (int)0xffffffff) {
-          $lo = 0;
-          $hi++;
-        } else {
-          $lo++;
-        }
-      }
-
-      // Now do the zigging and zagging.
-      $xorer = 0;
-      if ($neg) {
-        $xorer = 0xffffffff;
-      }
-      $lowbit = ($lo >> 31) & 1;
-      $hi = ($hi << 1) | $lowbit;
-      $lo = ($lo << 1);
-      $lo = ($lo ^ $xorer) & 0xffffffff;
-      $hi = ($hi ^ $xorer) & 0xffffffff;
-
-      // now write out the varint, ensuring we shift both hi and lo
-      $out = "";
-      while (true) {
-        if (($lo & ~0x7f) === 0 &&
-           $hi === 0) {
-          $out .= chr($lo);
-          break;
-        } else {
-          $out .= chr(($lo & 0xff) | 0x80);
-          $lo = $lo >> 7;
-          $lo = $lo | ($hi << 25);
-          $hi = $hi >> 7;
-          // Right shift carries sign, but we don't want it to.
-          $hi = $hi & (127 << 25);
-        }
-      }
-
-      $ret = TStringFuncFactory::create()->strlen($out);
-      $this->trans_->write($out, $ret);
-
-      return $ret;
-    } else {
-      return $this->writeVarint($this->toZigZag($value, 64));
-    }
-  }
-}
-
-/**
- * Compact Protocol Factory
- */
-class TCompcatProtocolFactory implements TProtocolFactory {
-
-  public function __construct() {
-  }
-
-  public function getProtocol($trans) {
-    return new TCompactProtocol($trans);
-  }
-}
-
diff --git a/lib/php/src/protocol/TJSONProtocol.php b/lib/php/src/protocol/TJSONProtocol.php
index b7eaa07..e69de29 100755
--- a/lib/php/src/protocol/TJSONProtocol.php
+++ b/lib/php/src/protocol/TJSONProtocol.php
@@ -1,808 +0,0 @@
-<?php
-
-/*
- * 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.
- *
- * @package thrift.protocol
- */
-
-/**
- * JSON implementation of thrift protocol, ported from Java.
- */
-class TJSONProtocol extends TProtocol
-{
-    const COMMA = ',';
-    const COLON = ':';
-    const LBRACE = '{';
-    const RBRACE = '}';
-    const LBRACKET = '[';
-    const RBRACKET = ']';
-    const QUOTE = '"';
-    const BACKSLASH = '\\';
-    const ZERO = '0';
-    const ESCSEQ = '\\';
-    const DOUBLEESC = '__DOUBLE_ESCAPE_SEQUENCE__';
-
-    const VERSION = 1;
-
-    public static $JSON_CHAR_TABLE = array(
-        /*  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
-        0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
-        1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
-    );
-
-    public static $ESCAPE_CHARS = array('"', '\\', "b", "f", "n", "r", "t");
-
-    public static $ESCAPE_CHAR_VALS = array(
-        '"', '\\', "\x08", "\f", "\n", "\r", "\t",
-    );
-
-    const NAME_BOOL = "tf";
-    const NAME_BYTE = "i8";
-    const NAME_I16 = "i16";
-    const NAME_I32 = "i32";
-    const NAME_I64 = "i64";
-    const NAME_DOUBLE = "dbl";
-    const NAME_STRUCT = "rec";
-    const NAME_STRING = "str";
-    const NAME_MAP = "map";
-    const NAME_LIST = "lst";
-    const NAME_SET = "set";
-
-    private function getTypeNameForTypeID($typeID)
-    {
-        switch ($typeID) {
-            case TType::BOOL:
-                return self::NAME_BOOL;
-            case TType::BYTE:
-                return self::NAME_BYTE;
-            case TType::I16:
-                return self::NAME_I16;
-            case TType::I32:
-                return self::NAME_I32;
-            case TType::I64:
-                return self::NAME_I64;
-            case TType::DOUBLE:
-                return self::NAME_DOUBLE;
-            case TType::STRING:
-                return self::NAME_STRING;
-            case TType::STRUCT:
-                return self::NAME_STRUCT;
-            case TType::MAP:
-                return self::NAME_MAP;
-            case TType::SET:
-                return self::NAME_SET;
-            case TType::LST:
-                return self::NAME_LIST;
-            default:
-                throw new TProtocolException("Unrecognized type", TProtocolException::UNKNOWN);
-        }
-    }
-
-    private function getTypeIDForTypeName($name)
-    {
-        $result = TType::STOP;
-
-        if (strlen($name) > 1) {
-            switch (substr($name, 0, 1)) {
-                case 'd':
-                    $result = TType::DOUBLE;
-                    break;
-                case 'i':
-                    switch (substr($name, 1, 1)) {
-                        case '8':
-                            $result = TType::BYTE;
-                            break;
-                        case '1':
-                            $result = TType::I16;
-                            break;
-                        case '3':
-                            $result = TType::I32;
-                            break;
-                        case '6':
-                            $result = TType::I64;
-                            break;
-                    }
-                    break;
-                case 'l':
-                    $result = TType::LST;
-                    break;
-                case 'm':
-                    $result = TType::MAP;
-                    break;
-                case 'r':
-                    $result = TType::STRUCT;
-                    break;
-                case 's':
-                    if (substr($name, 1, 1) == 't') {
-                        $result = TType::STRING;
-                    }
-                    else if (substr($name, 1, 1) == 'e') {
-                        $result = TType::SET;
-                    }
-                    break;
-                case 't':
-                    $result = TType::BOOL;
-                    break;
-            }
-        }
-        if ($result == TType::STOP) {
-            throw new TProtocolException("Unrecognized type", TProtocolException::INVALID_DATA);
-        }
-        return $result;
-    }
-
-    public $contextStack_ = array();
-    public $context_;
-    public $reader_;
-
-    private function pushContext($c) {
-        array_push($this->contextStack_, $this->context_);
-        $this->context_ = $c;
-    }
-
-    private function popContext() {
-        $this->context_ = array_pop($this->contextStack_);
-    }
-
-    public function __construct($trans) {
-        parent::__construct($trans);
-        $this->context_ = new TJSONProtocol_JSONBaseContext();
-        $this->reader_ = new TJSONProtocol_LookaheadReader($this);
-    }
-
-    public function reset() {
-        $this->contextStack_ = array();
-        $this->context_ = new TJSONProtocol_JSONBaseContext();
-        $this->reader_ = new TJSONProtocol_LookaheadReader($this);
-    }
-
-    private $tmpbuf_ = array(4);
-
-    public function readJSONSyntaxChar($b) {
-        $ch = $this->reader_->read();
-
-        if (substr($ch, 0, 1) != $b) {
-            throw new TProtocolException("Unexpected character: " . $ch, TProtocolException::INVALID_DATA);
-        }
-    }
-
-    private function hexVal($s) {
-        for ($i = 0; $i < strlen($s); $i++) {
-            $ch = substr($s, $i, 1);
-
-            if (!($ch >= "a" && $ch <= "f") && !($ch >= "0" && $ch <= "9")) {
-                throw new TProtocolException("Expected hex character " . $ch, TProtocolException::INVALID_DATA);
-            }
-        }
-
-        return hexdec($s);
-    }
-
-    private function hexChar($val) {
-        return dechex($val);
-    }
-
-    private function writeJSONString($b) {
-        $this->context_->write();
-
-        if (is_numeric($b) && $this->context_->escapeNum()) {
-            $this->trans_->write(self::QUOTE);
-        } 
-
-        $this->trans_->write(json_encode($b));
-
-        if (is_numeric($b) && $this->context_->escapeNum()) {
-            $this->trans_->write(self::QUOTE);
-        } 
-    }
-
-    private function writeJSONInteger($num) {
-        $this->context_->write();
-
-        if ($this->context_->escapeNum()) {
-            $this->trans_->write(self::QUOTE);
-        }
-
-        $this->trans_->write($num);
-
-        if ($this->context_->escapeNum()) {
-            $this->trans_->write(self::QUOTE);
-        }
-    }
-
-    private function writeJSONDouble($num) {
-        $this->context_->write();
-
-        if ($this->context_->escapeNum()) {
-            $this->trans_->write(self::QUOTE);
-        }
-
-        $this->trans_->write(json_encode($num));
-
-        if ($this->context_->escapeNum()) {
-            $this->trans_->write(self::QUOTE);
-        }
-    }
-
-    private function writeJSONBase64($data) {
-        $this->context_->write();
-        $this->trans_->write(self::QUOTE);
-        $this->trans_->write(json_encode(base64_encode($data)));
-        $this->trans_->write(self::QUOTE);
-    }
-
-    private function writeJSONObjectStart() {
-      $this->context_->write();
-      $this->trans_->write(self::LBRACE);
-      $this->pushContext(new TJSONProtocol_JSONPairContext($this));
-    }
-
-    private function writeJSONObjectEnd() {
-      $this->popContext();
-      $this->trans_->write(self::RBRACE);
-    }
-
-    private function writeJSONArrayStart() {
-      $this->context_->write();
-      $this->trans_->write(self::LBRACKET);
-      $this->pushContext(new TJSONProtocol_JSONListContext($this));
-    }
-
-    private function writeJSONArrayEnd() {
-      $this->popContext();
-      $this->trans_->write(self::RBRACKET);
-    }
-
-    private function readJSONString($skipContext) {
-      if (!$skipContext) {
-        $this->context_->read();
-      }
-
-      $jsonString = '';
-      $lastChar = NULL;
-      while (true) {
-        $ch = $this->reader_->read();
-        $jsonString .= $ch;
-        if ($ch == self::QUOTE &&
-          $lastChar !== NULL &&
-            $lastChar !== self::ESCSEQ) {
-          break;
-        }
-        if ($ch == self::ESCSEQ && $lastChar == self::ESCSEQ) {
-          $lastChar = self::DOUBLEESC;
-        } else {
-          $lastChar = $ch;
-        }
-      }
-      return json_decode($jsonString);
-    }
-
-    private function isJSONNumeric($b) {
-        switch ($b) {
-            case '+':
-            case '-':
-            case '.':
-            case '0':
-            case '1':
-            case '2':
-            case '3':
-            case '4':
-            case '5':
-            case '6':
-            case '7':
-            case '8':
-            case '9':
-            case 'E':
-            case 'e':
-              return true;
-            }
-        return false;
-    }
-
-    private function readJSONNumericChars() {
-        $strbld = array();
-
-        while (true) {
-            $ch = $this->reader_->peek();
-
-            if (!$this->isJSONNumeric($ch)) {
-                break;
-            }
-
-            $strbld[] = $this->reader_->read();
-        }
-
-        return implode("", $strbld);
-    }
-
-    private function readJSONInteger() {
-        $this->context_->read();
-
-        if ($this->context_->escapeNum()) {
-            $this->readJSONSyntaxChar(self::QUOTE);
-        }
-
-        $str = $this->readJSONNumericChars();
-
-        if ($this->context_->escapeNum()) {
-            $this->readJSONSyntaxChar(self::QUOTE);
-        }
-
-        if (!is_numeric($str)) {
-            throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA);
-        }
-
-        return intval($str);
-    }
-
-    /**
-     * Identical to readJSONInteger but without the final cast.
-     * Needed for proper handling of i64 on 32 bit machines.  Why a
-     * separate function?  So we don't have to force the rest of the
-     * use cases through the extra conditional.
-     */
-    private function readJSONIntegerAsString() {
-        $this->context_->read();
-
-        if ($this->context_->escapeNum()) {
-            $this->readJSONSyntaxChar(self::QUOTE);
-        }
-
-        $str = $this->readJSONNumericChars();
-
-        if ($this->context_->escapeNum()) {
-            $this->readJSONSyntaxChar(self::QUOTE);
-        }
-
-        if (!is_numeric($str)) {
-            throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA);
-        }
-
-        return $str;
-    }
-
-    private function readJSONDouble() {
-        $this->context_->read();
-
-        if (substr($this->reader_->peek(), 0, 1) == self::QUOTE) {
-            $arr = $this->readJSONString(true);
-
-            if ($arr == "NaN") {
-                return NAN;
-            } else if ($arr == "Infinity") {
-                return INF;
-            } else if (!$this->context_->escapeNum()) {
-                throw new TProtocolException("Numeric data unexpectedly quoted " . $arr,
-                                              TProtocolException::INVALID_DATA);
-            }
-
-            return floatval($arr);
-        } else {
-            if ($this->context_->escapeNum()) {
-                $this->readJSONSyntaxChar(self::QUOTE);
-            }
-
-            return floatval($this->readJSONNumericChars());
-        }
-    }
-
-    private function readJSONBase64() {
-        $arr = $this->readJSONString(false);
-        $data = base64_decode($arr, true);
-
-        if ($data === false) {
-            throw new TProtocolException("Invalid base64 data " . $arr, TProtocolException::INVALID_DATA);
-        }
-
-        return $data;
-    }
-
-    private function readJSONObjectStart() {
-        $this->context_->read();
-        $this->readJSONSyntaxChar(self::LBRACE);
-        $this->pushContext(new TJSONProtocol_JSONPairContext($this));
-    }
-
-    private function readJSONObjectEnd() {
-        $this->readJSONSyntaxChar(self::RBRACE);
-        $this->popContext();
-    }
-
-    private function readJSONArrayStart()
-    {
-        $this->context_->read();
-        $this->readJSONSyntaxChar(self::LBRACKET);
-        $this->pushContext(new TJSONProtocol_JSONListContext($this));
-    }
-
-    private function readJSONArrayEnd() {
-        $this->readJSONSyntaxChar(self::RBRACKET);
-        $this->popContext();
-    }
-
-    /**
-     * Writes the message header
-     *
-     * @param string $name Function name
-     * @param int $type message type TMessageType::CALL or TMessageType::REPLY
-     * @param int $seqid The sequence id of this message
-     */
-    public function writeMessageBegin($name, $type, $seqid) {
-        $this->writeJSONArrayStart();
-        $this->writeJSONInteger(self::VERSION);
-        $this->writeJSONString($name);
-        $this->writeJSONInteger($type);
-        $this->writeJSONInteger($seqid);
-    }
-
-    /**
-     * Close the message
-     */
-    public function writeMessageEnd() {
-        $this->writeJSONArrayEnd();
-    }
-
-    /**
-     * Writes a struct header.
-     *
-     * @param string     $name Struct name
-     * @throws TException on write error
-     * @return int How many bytes written
-     */
-    public function writeStructBegin($name) {
-        $this->writeJSONObjectStart();
-    }
-
-    /**
-     * Close a struct.
-     *
-     * @throws TException on write error
-     * @return int How many bytes written
-     */
-    public function writeStructEnd() {
-        $this->writeJSONObjectEnd();
-    }
-
-    public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
-        $this->writeJSONInteger($fieldId);
-        $this->writeJSONObjectStart();
-        $this->writeJSONString($this->getTypeNameForTypeID($fieldType));
-    }
-
-    public function writeFieldEnd() {
-        $this->writeJsonObjectEnd();
-    }
-
-    public function writeFieldStop() {
-    }
-
-    public function writeMapBegin($keyType, $valType, $size) {
-        $this->writeJSONArrayStart();
-        $this->writeJSONString($this->getTypeNameForTypeID($keyType));
-        $this->writeJSONString($this->getTypeNameForTypeID($valType));
-        $this->writeJSONInteger($size);
-        $this->writeJSONObjectStart();
-    }
-
-    public function writeMapEnd() {
-        $this->writeJSONObjectEnd();
-        $this->writeJSONArrayEnd();
-    }
-
-    public function writeListBegin($elemType, $size) {
-        $this->writeJSONArrayStart();
-        $this->writeJSONString($this->getTypeNameForTypeID($elemType));
-        $this->writeJSONInteger($size);
-    }
-
-    public function writeListEnd() {
-        $this->writeJSONArrayEnd();
-    }
-
-    public function writeSetBegin($elemType, $size) {
-        $this->writeJSONArrayStart();
-        $this->writeJSONString($this->getTypeNameForTypeID($elemType));
-        $this->writeJSONInteger($size);
-    }
-
-    public function writeSetEnd() {
-        $this->writeJSONArrayEnd();
-    }
-
-    public function writeBool($bool) {
-        $this->writeJSONInteger($bool ? 1 : 0);
-    }
-
-    public function writeByte($byte) {
-        $this->writeJSONInteger($byte);
-    }
-
-    public function writeI16($i16) {
-        $this->writeJSONInteger($i16);
-    }
-
-    public function writeI32($i32) {
-        $this->writeJSONInteger($i32);
-    }
-
-    public function writeI64($i64) {
-        $this->writeJSONInteger($i64);
-    }
-
-    public function writeDouble($dub) {
-        $this->writeJSONDouble($dub);
-    }
-
-    public function writeString($str) {
-        $this->writeJSONString($str);
-    }
-
-    /**
-     * Reads the message header
-     *
-     * @param string $name Function name
-     * @param int $type message type TMessageType::CALL or TMessageType::REPLY
-     * @parem int $seqid The sequence id of this message
-     */
-    public function readMessageBegin(&$name, &$type, &$seqid) {
-        $this->readJSONArrayStart();
-
-        if ($this->readJSONInteger() != self::VERSION) {
-            throw new TProtocolException("Message contained bad version", TProtocolException::BAD_VERSION);
-        }
-
-        $name = $this->readJSONString(false);
-        $type = $this->readJSONInteger();
-        $seqid = $this->readJSONInteger();
-
-        return true;
-    }
-
-    /**
-     * Read the close of message
-     */
-    public function readMessageEnd() {
-        $this->readJSONArrayEnd();
-    }
-
-    public function readStructBegin(&$name) {
-        $this->readJSONObjectStart();
-        return 0;
-    }
-
-    public function readStructEnd() {
-        $this->readJSONObjectEnd();
-    }
-
-    public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
-        $ch = $this->reader_->peek();
-        $name = "";
-
-        if (substr($ch, 0, 1) == self::RBRACE) {
-            $fieldType = TType::STOP;
-        } else {
-            $fieldId = $this->readJSONInteger();
-            $this->readJSONObjectStart();
-            $fieldType = $this->getTypeIDForTypeName($this->readJSONString(false));
-        }
-    }
-
-    public function readFieldEnd() {
-        $this->readJSONObjectEnd();
-    }
-
-    public function readMapBegin(&$keyType, &$valType, &$size) {
-        $this->readJSONArrayStart();
-        $keyType = $this->getTypeIDForTypeName($this->readJSONString(false));
-        $valType = $this->getTypeIDForTypeName($this->readJSONString(false));
-        $size = $this->readJSONInteger();
-        $this->readJSONObjectStart();
-    }
-
-    public function readMapEnd() {
-        $this->readJSONObjectEnd();
-        $this->readJSONArrayEnd();
-    }
-
-    public function readListBegin(&$elemType, &$size) {
-        $this->readJSONArrayStart();
-        $elemType = $this->getTypeIDForTypeName($this->readJSONString(false));
-        $size = $this->readJSONInteger();
-        return true;
-    }
-
-    public function readListEnd() {
-        $this->readJSONArrayEnd();
-    }
-
-    public function readSetBegin(&$elemType, &$size) {
-        $this->readJSONArrayStart();
-        $elemType = $this->getTypeIDForTypeName($this->readJSONString(false));
-        $size = $this->readJSONInteger();
-        return true;
-    }
-
-    public function readSetEnd() {
-        $this->readJSONArrayEnd();
-    }
-
-    public function readBool(&$bool) {
-        $bool = $this->readJSONInteger() == 0 ? false : true;
-        return true;
-    }
-
-    public function readByte(&$byte) {
-        $byte = $this->readJSONInteger();
-        return true;
-    }
-
-    public function readI16(&$i16) {
-        $i16 = $this->readJSONInteger();
-        return true;
-    }
-
-    public function readI32(&$i32) {
-        $i32 = $this->readJSONInteger();
-        return true;
-    }
-
-    public function readI64(&$i64) {
-        if ( PHP_INT_SIZE === 4 ) {
-            $i64 = $this->readJSONIntegerAsString();
-        } else {
-            $i64 = $this->readJSONInteger();
-        }
-        return true;
-    }
-
-    public function readDouble(&$dub) {
-        $dub = $this->readJSONDouble();
-        return true;
-    }
-
-    public function readString(&$str) {
-        $str = $this->readJSONString(false);
-        return true;
-    }
-}
-
-/**
- * JSON Protocol Factory
- */
-class TJSONProtocolFactory implements TProtocolFactory
-{
-    public function __construct()
-    {
-    }
-
-    public function getProtocol($trans)
-    {
-        return new TJSONProtocol($trans);
-    }
-}
-
-class TJSONProtocol_JSONBaseContext
-{
-    function escapeNum()
-    {
-        return false;
-    }
-
-    function write()
-    {
-    }
-
-    function read()
-    {
-    }
-}
-
-class TJSONProtocol_JSONListContext extends TJSONProtocol_JSONBaseContext
-{
-    private $first_ = true;
-    private $p_;
-
-    public function __construct($p) {
-        $this->p_ = $p;
-    }
-
-    public function write() {
-        if ($this->first_) {
-            $this->first_ = false;
-        } else {
-            $this->p_->getTransport()->write(TJSONProtocol::COMMA);
-        }
-    }
-
-    public function read() {
-        if ($this->first_) {
-            $this->first_ = false;
-        } else {
-            $this->p_->readJSONSyntaxChar(TJSONProtocol::COMMA);
-        }
-    }
-}
-
-class TJSONProtocol_JSONPairContext extends TJSONProtocol_JSONBaseContext {
-    private $first_ = true;
-    private $colon_ = true;
-    private $p_ = null;
-
-    public function __construct($p) {
-        $this->p_ = $p;
-    }
-
-    public function write() {
-        if ($this->first_) {
-            $this->first_ = false;
-            $this->colon_ = true;
-        } else {
-            $this->p_->getTransport()->write($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA);
-            $this->colon_ = !$this->colon_;
-        }
-    }
-
-    public function read() {
-        if ($this->first_) {
-            $this->first_ = false;
-            $this->colon_ = true;
-        } else {
-            $this->p_->readJSONSyntaxChar($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA);
-            $this->colon_ = !$this->colon_;
-        }
-    }
-
-    public function escapeNum() {
-        return $this->colon_;
-    }
-}
-
-class TJSONProtocol_LookaheadReader
-{
-    private $hasData_ = false;
-    private $data_ = array();
-    private $p_;
-
-    public function __construct($p)
-    {
-        $this->p_ = $p;
-    }
-
-    public function read() {
-        if ($this->hasData_) {
-            $this->hasData_ = false;
-        } else {
-            $this->data_ = $this->p_->getTransport()->readAll(1);
-        }
-
-        return substr($this->data_, 0, 1);
-    }
-
-    public function peek() {
-        if (!$this->hasData_) {
-            $this->data_ = $this->p_->getTransport()->readAll(1);
-        }
-
-        $this->hasData_ = true;
-        return substr($this->data_, 0, 1);
-    }
-}
-
-
diff --git a/lib/php/src/protocol/TProtocol.php b/lib/php/src/protocol/TProtocol.php
index 239648e..e69de29 100644
--- a/lib/php/src/protocol/TProtocol.php
+++ b/lib/php/src/protocol/TProtocol.php
@@ -1,376 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.protocol
- */
-
-
-/**
- * Protocol module. Contains all the types and definitions needed to implement
- * a protocol encoder/decoder.
- *
- * @package thrift.protocol
- */
-
-/**
- * Protocol exceptions
- */
-class TProtocolException extends TException {
-  const UNKNOWN = 0;
-  const INVALID_DATA = 1;
-  const NEGATIVE_SIZE = 2;
-  const SIZE_LIMIT = 3;
-  const BAD_VERSION = 4;
-
-  function __construct($message=null, $code=0) {
-    parent::__construct($message, $code);
-  }
-}
-
-/**
- * Protocol base class module.
- */
-abstract class TProtocol {
-  // The below may seem silly, but it is to get around the problem that the
-  // "instanceof" operator can only take in a T_VARIABLE and not a T_STRING
-  // or T_CONSTANT_ENCAPSED_STRING. Using "is_a()" instead of "instanceof" is
-  // a workaround but is deprecated in PHP5. This is used in the generated
-  // deserialization code.
-  static $TBINARYPROTOCOLACCELERATED = 'TBinaryProtocolAccelerated';
-
-  /**
-   * Underlying transport
-   *
-   * @var TTransport
-   */
-  protected $trans_;
-
-  /**
-   * Constructor
-   */
-  protected function __construct($trans) {
-    $this->trans_ = $trans;
-  }
-
-  /**
-   * Accessor for transport
-   *
-   * @return TTransport
-   */
-  public function getTransport() {
-    return $this->trans_;
-  }
-
-  /**
-   * Writes the message header
-   *
-   * @param string $name Function name
-   * @param int $type message type TMessageType::CALL or TMessageType::REPLY
-   * @param int $seqid The sequence id of this message
-   */
-  public abstract function writeMessageBegin($name, $type, $seqid);
-
-  /**
-   * Close the message
-   */
-  public abstract function writeMessageEnd();
-
-  /**
-   * Writes a struct header.
-   *
-   * @param string     $name Struct name
-   * @throws TException on write error
-   * @return int How many bytes written
-   */
-  public abstract function writeStructBegin($name);
-
-  /**
-   * Close a struct.
-   *
-   * @throws TException on write error
-   * @return int How many bytes written
-   */
-  public abstract function writeStructEnd();
-
-  /*
-   * Starts a field.
-   *
-   * @param string     $name Field name
-   * @param int        $type Field type
-   * @param int        $fid  Field id
-   * @throws TException on write error
-   * @return int How many bytes written
-   */
-  public abstract function writeFieldBegin($fieldName, $fieldType, $fieldId);
-
-  public abstract function writeFieldEnd();
-
-  public abstract function writeFieldStop();
-
-  public abstract function writeMapBegin($keyType, $valType, $size);
-
-  public abstract function writeMapEnd();
-
-  public abstract function writeListBegin($elemType, $size);
-
-  public abstract function writeListEnd();
-
-  public abstract function writeSetBegin($elemType, $size);
-
-  public abstract function writeSetEnd();
-
-  public abstract function writeBool($bool);
-
-  public abstract function writeByte($byte);
-
-  public abstract function writeI16($i16);
-
-  public abstract function writeI32($i32);
-
-  public abstract function writeI64($i64);
-
-  public abstract function writeDouble($dub);
-
-  public abstract function writeString($str);
-
-  /**
-   * Reads the message header
-   *
-   * @param string $name Function name
-   * @param int $type message type TMessageType::CALL or TMessageType::REPLY
-   * @parem int $seqid The sequence id of this message
-   */
-  public abstract function readMessageBegin(&$name, &$type, &$seqid);
-
-  /**
-   * Read the close of message
-   */
-  public abstract function readMessageEnd();
-
-  public abstract function readStructBegin(&$name);
-
-  public abstract function readStructEnd();
-
-  public abstract function readFieldBegin(&$name, &$fieldType, &$fieldId);
-
-  public abstract function readFieldEnd();
-
-  public abstract function readMapBegin(&$keyType, &$valType, &$size);
-
-  public abstract function readMapEnd();
-
-  public abstract function readListBegin(&$elemType, &$size);
-
-  public abstract function readListEnd();
-
-  public abstract function readSetBegin(&$elemType, &$size);
-
-  public abstract function readSetEnd();
-
-  public abstract function readBool(&$bool);
-
-  public abstract function readByte(&$byte);
-
-  public abstract function readI16(&$i16);
-
-  public abstract function readI32(&$i32);
-
-  public abstract function readI64(&$i64);
-
-  public abstract function readDouble(&$dub);
-
-  public abstract function readString(&$str);
-
-  /**
-   * The skip function is a utility to parse over unrecognized date without
-   * causing corruption.
-   *
-   * @param TType $type What type is it
-   */
-  public function skip($type) {
-    switch ($type) {
-    case TType::BOOL:
-      return $this->readBool($bool);
-    case TType::BYTE:
-      return $this->readByte($byte);
-    case TType::I16:
-      return $this->readI16($i16);
-    case TType::I32:
-      return $this->readI32($i32);
-    case TType::I64:
-      return $this->readI64($i64);
-    case TType::DOUBLE:
-      return $this->readDouble($dub);
-    case TType::STRING:
-      return $this->readString($str);
-    case TType::STRUCT:
-      {
-        $result = $this->readStructBegin($name);
-        while (true) {
-          $result += $this->readFieldBegin($name, $ftype, $fid);
-          if ($ftype == TType::STOP) {
-            break;
-          }
-          $result += $this->skip($ftype);
-          $result += $this->readFieldEnd();
-        }
-        $result += $this->readStructEnd();
-        return $result;
-      }
-    case TType::MAP:
-      {
-        $result = $this->readMapBegin($keyType, $valType, $size);
-        for ($i = 0; $i < $size; $i++) {
-          $result += $this->skip($keyType);
-          $result += $this->skip($valType);
-        }
-        $result += $this->readMapEnd();
-        return $result;
-      }
-    case TType::SET:
-      {
-        $result = $this->readSetBegin($elemType, $size);
-        for ($i = 0; $i < $size; $i++) {
-          $result += $this->skip($elemType);
-        }
-        $result += $this->readSetEnd();
-        return $result;
-      }
-    case TType::LST:
-      {
-        $result = $this->readListBegin($elemType, $size);
-        for ($i = 0; $i < $size; $i++) {
-          $result += $this->skip($elemType);
-        }
-        $result += $this->readListEnd();
-        return $result;
-      }
-    default:
-      throw new TProtocolException('Unknown field type: '.$type,
-                                   TProtocolException::INVALID_DATA);
-    }
-  }
-
-  /**
-   * Utility for skipping binary data
-   *
-   * @param TTransport $itrans TTransport object
-   * @param int        $type   Field type
-   */
-  public static function skipBinary($itrans, $type) {
-    switch ($type) {
-    case TType::BOOL:
-      return $itrans->readAll(1);
-    case TType::BYTE:
-      return $itrans->readAll(1);
-    case TType::I16:
-      return $itrans->readAll(2);
-    case TType::I32:
-      return $itrans->readAll(4);
-    case TType::I64:
-      return $itrans->readAll(8);
-    case TType::DOUBLE:
-      return $itrans->readAll(8);
-    case TType::STRING:
-      $len = unpack('N', $itrans->readAll(4));
-      $len = $len[1];
-      if ($len > 0x7fffffff) {
-        $len = 0 - (($len - 1) ^ 0xffffffff);
-      }
-      return 4 + $itrans->readAll($len);
-    case TType::STRUCT:
-      {
-        $result = 0;
-        while (true) {
-          $ftype = 0;
-          $fid = 0;
-          $data = $itrans->readAll(1);
-          $arr = unpack('c', $data);
-          $ftype = $arr[1];
-          if ($ftype == TType::STOP) {
-            break;
-          }
-          // I16 field id
-          $result += $itrans->readAll(2);
-          $result += self::skipBinary($itrans, $ftype);
-        }
-        return $result;
-      }
-    case TType::MAP:
-      {
-        // Ktype
-        $data = $itrans->readAll(1);
-        $arr = unpack('c', $data);
-        $ktype = $arr[1];
-        // Vtype
-        $data = $itrans->readAll(1);
-        $arr = unpack('c', $data);
-        $vtype = $arr[1];
-        // Size
-        $data = $itrans->readAll(4);
-        $arr = unpack('N', $data);
-        $size = $arr[1];
-        if ($size > 0x7fffffff) {
-          $size = 0 - (($size - 1) ^ 0xffffffff);
-        }
-        $result = 6;
-        for ($i = 0; $i < $size; $i++) {
-          $result += self::skipBinary($itrans, $ktype);
-          $result += self::skipBinary($itrans, $vtype);
-        }
-        return $result;
-      }
-    case TType::SET:
-    case TType::LST:
-      {
-        // Vtype
-        $data = $itrans->readAll(1);
-        $arr = unpack('c', $data);
-        $vtype = $arr[1];
-        // Size
-        $data = $itrans->readAll(4);
-        $arr = unpack('N', $data);
-        $size = $arr[1];
-        if ($size > 0x7fffffff) {
-          $size = 0 - (($size - 1) ^ 0xffffffff);
-        }
-        $result = 5;
-        for ($i = 0; $i < $size; $i++) {
-          $result += self::skipBinary($itrans, $vtype);
-        }
-        return $result;
-      }
-    default:
-      throw new TProtocolException('Unknown field type: '.$type,
-                                   TProtocolException::INVALID_DATA);
-    }
-  }
-}
-
-/**
- * Protocol factory creates protocol objects from transports
- */
-interface TProtocolFactory {
-  /**
-   * Build a protocol from the base transport
-   *
-   * @return TProtocol protocol
-   */
-  public function getProtocol($trans);
-}
diff --git a/lib/php/src/server/TForkingServer.php b/lib/php/src/server/TForkingServer.php
index e2370cb..e69de29 100644
--- a/lib/php/src/server/TForkingServer.php
+++ b/lib/php/src/server/TForkingServer.php
@@ -1,114 +0,0 @@
-<?php
-
-include_once $GLOBALS['THRIFT_ROOT'].'/server/TServer.php';
-
-/**
- * A forking implementation of a Thrift server.
- *
- * @package thrift.server
- */
-class TForkingServer extends TServer {
-  /**
-   * Flag for the main serving loop
-   *
-   * @var bool
-   */
-  private $stop_ = false;
-
-  /**
-   * List of children.
-   *
-   * @var array
-   */
-  protected $children_ = array();
-
-  /**
-   * Listens for new client using the supplied
-   * transport. We fork when a new connection
-   * arrives.
-   *
-   * @return void
-   */
-  public function serve() {
-    $this->transport_->listen();
-
-    while (!$this->stop_) {
-      try {
-        $transport = $this->transport_->accept();
-
-        if ($transport != null) {
-          $pid = pcntl_fork();
-
-          if ($pid > 0) {
-            $this->handleParent($transport, $pid);
-          }
-          else if ($pid === 0) {
-            $this->handleChild($transport);
-          }
-          else {
-            throw new TException('Failed to fork');
-          }
-        }
-      }
-      catch (TTransportException $e) { }
-
-      $this->collectChildren();
-    }
-  }
-
-  /**
-   * Code run by the parent
-   *
-   * @param TTransport $transport
-   * @param int $pid
-   * @return void
-   */
-  private function handleParent(TTransport $transport, $pid) {
-    $this->children_[$pid] = $transport;
-  }
-
-  /**
-   * Code run by the child.
-   *
-   * @param TTransport $transport
-   * @return void
-   */
-  private function handleChild(TTransport $transport) {
-    try {
-      $inputTransport = $this->inputTransportFactory_->getTransport($transport);
-      $outputTransport = $this->outputTransportFactory_->getTransport($transport);
-      $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport);
-      $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport);
-      while ($this->processor_->process($inputProtocol, $outputProtocol)) { }
-      @$transport->close();
-    }
-    catch (TTransportException $e) { }
-    
-    exit(0);
-  }
-
-  /**
-   * Collects any children we may have
-   *
-   * @return void
-   */
-  private function collectChildren() {
-    foreach ($this->children_ as $pid => $transport) {
-      if (pcntl_waitpid($pid, $status, WNOHANG) > 0) {
-        unset($this->children_[$pid]);
-        if ($transport) @$transport->close();
-      }
-    }
-  }
-
-  /**
-   * Stops the server running. Kills the transport
-   * and then stops the main serving loop
-   *
-   * @return void
-   */
-  public function stop() {
-    $this->transport_->close();
-    $this->stop_ = true;
-  }
-}
diff --git a/lib/php/src/server/TServer.php b/lib/php/src/server/TServer.php
index b25a9ee..e69de29 100644
--- a/lib/php/src/server/TServer.php
+++ b/lib/php/src/server/TServer.php
@@ -1,95 +0,0 @@
-<?php
-
-/**
- * Generic class for a Thrift server.
- *
- * @package thrift.server
- */
-abstract class TServer {
-
-  /**
-   * Processor to handle new clients
-   *
-   * @var TProcessor
-   */
-  protected $processor_;
-
-  /**
-   * Server transport to be used for listening
-   * and accepting new clients
-   *
-   * @var TServerTransport
-   */
-  protected $transport_;
-
-  /**
-   * Input transport factory
-   *
-   * @var TTransportFactory
-   */
-  protected $inputTransportFactory_;
-
-  /**
-   * Output transport factory
-   *
-   * @var TTransportFactory
-   */
-  protected $outputTransportFactory_;
-
-  /**
-   * Input protocol factory
-   *
-   * @var TProtocolFactory
-   */
-  protected $inputProtocolFactory_;
-
-  /**
-   * Output protocol factory
-   *
-   * @var TProtocolFactory
-   */
-  protected $outputProtocolFactory_;
-
-  /**
-   * Sets up all the factories, etc
-   *
-   * @param object $processor
-   * @param TServerTransport $transport
-   * @param TTransportFactory $inputTransportFactory
-   * @param TTransportFactory $outputTransportFactory
-   * @param TProtocolFactory $inputProtocolFactory
-   * @param TProtocolFactory $outputProtocolFactory
-   * @return void
-   */
-  public function __construct($processor,
-                              TServerTransport $transport,
-                              TTransportFactory $inputTransportFactory,
-                              TTransportFactory $outputTransportFactory,
-                              TProtocolFactory $inputProtocolFactory,
-                              TProtocolFactory $outputProtocolFactory) {
-    $this->processor_ = $processor;
-    $this->transport_ = $transport;
-    $this->inputTransportFactory_ = $inputTransportFactory;
-    $this->outputTransportFactory_ = $outputTransportFactory;
-    $this->inputProtocolFactory_ = $inputProtocolFactory;
-    $this->outputProtocolFactory_ = $outputProtocolFactory;
-  }
-
-  /**
-   * Serves the server. This should never return
-   * unless a problem permits it to do so or it
-   * is interrupted intentionally
-   *
-   * @abstract
-   * @return void
-   */
-  abstract public function serve();
-
-  /**
-   * Stops the server serving
-   *
-   * @abstract
-   * @return void
-   */
-  abstract public function stop();
-}
diff --git a/lib/php/src/server/TSimpleServer.php b/lib/php/src/server/TSimpleServer.php
index f7d0a32..e69de29 100644
--- a/lib/php/src/server/TSimpleServer.php
+++ b/lib/php/src/server/TSimpleServer.php
@@ -1,54 +0,0 @@
-<?php
-
-include_once $GLOBALS['THRIFT_ROOT'].'/server/TServer.php';
-
-/**
- * Simple implemtation of a Thrift server.
- *
- * @package thrift.server
- */
-class TSimpleServer extends TServer {
-  /**
-   * Flag for the main serving loop
-   *
-   * @var bool
-   */
-  private $stop_ = false;
-
-  /**
-   * Listens for new client using the supplied
-   * transport. It handles TTransportExceptions
-   * to avoid timeouts etc killing it
-   *
-   * @return void
-   */
-  public function serve() {
-    $this->transport_->listen();
-
-    while (!$this->stop_) {
-      try {
-        $transport = $this->transport_->accept();
-        
-        if ($transport != null) {
-          $inputTransport = $this->inputTransportFactory_->getTransport($transport);
-          $outputTransport = $this->outputTransportFactory_->getTransport($transport);
-          $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport);
-          $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport);
-          while ($this->processor_->process($inputProtocol, $outputProtocol)) { }
-        }
-      }
-      catch (TTransportException $e) { }
-    }
-  }
-
-  /**
-   * Stops the server running. Kills the transport
-   * and then stops the main serving loop
-   *
-   * @return void
-   */
-  public function stop() {
-    $this->transport_->close();
-    $this->stop_ = true;
-  }
-}
diff --git a/lib/php/src/transport/TBufferedTransport.php b/lib/php/src/transport/TBufferedTransport.php
index 9b27d02..e69de29 100644
--- a/lib/php/src/transport/TBufferedTransport.php
+++ b/lib/php/src/transport/TBufferedTransport.php
@@ -1,161 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Buffered transport. Stores data to an internal buffer that it doesn't
- * actually write out until flush is called. For reading, we do a greedy
- * read and then serve data out of the internal buffer.
- *
- * @package thrift.transport
- */
-class TBufferedTransport extends TTransport {
-
-  /**
-   * Constructor. Creates a buffered transport around an underlying transport
-   */
-  public function __construct($transport=null, $rBufSize=512, $wBufSize=512) {
-    $this->transport_ = $transport;
-    $this->rBufSize_ = $rBufSize;
-    $this->wBufSize_ = $wBufSize;
-  }
-
-  /**
-   * The underlying transport
-   *
-   * @var TTransport
-   */
-  protected $transport_ = null;
-
-  /**
-   * The receive buffer size
-   *
-   * @var int
-   */
-  protected $rBufSize_ = 512;
-
-  /**
-   * The write buffer size
-   *
-   * @var int
-   */
-  protected $wBufSize_ = 512;
-
-  /**
-   * The write buffer.
-   *
-   * @var string
-   */
-  protected $wBuf_ = '';
-
-  /**
-   * The read buffer.
-   *
-   * @var string
-   */
-  protected $rBuf_ = '';
-
-  public function isOpen() {
-    return $this->transport_->isOpen();
-  }
-
-  public function open() {
-    $this->transport_->open();
-  }
-
-  public function close() {
-    $this->transport_->close();
-  }
-
-  public function putBack($data) {
-    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
-      $this->rBuf_ = $data;
-    } else {
-      $this->rBuf_ = ($data . $this->rBuf_);
-    }
-  }
-
-  /**
-   * The reason that we customize readAll here is that the majority of PHP
-   * streams are already internally buffered by PHP. The socket stream, for
-   * example, buffers internally and blocks if you call read with $len greater
-   * than the amount of data available, unlike recv() in C.
-   *
-   * Therefore, use the readAll method of the wrapped transport inside
-   * the buffered readAll.
-   */
-  public function readAll($len) {
-    $have = TStringFuncFactory::create()->strlen($this->rBuf_);
-    if ($have == 0) {
-      $data = $this->transport_->readAll($len);
-    } else if ($have < $len) {
-      $data = $this->rBuf_;
-      $this->rBuf_ = '';
-      $data .= $this->transport_->readAll($len - $have);
-    } else if ($have == $len) {
-      $data = $this->rBuf_;
-      $this->rBuf_ = '';
-    } else if ($have > $len) {
-      $data = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
-      $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
-    }
-    return $data;
-  }
-
-  public function read($len) {
-    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
-      $this->rBuf_ = $this->transport_->read($this->rBufSize_);
-    }
-
-    if (TStringFuncFactory::create()->strlen($this->rBuf_) <= $len) {
-      $ret = $this->rBuf_;
-      $this->rBuf_ = '';
-      return $ret;
-    }
-
-    $ret = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
-    $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
-    return $ret;
-  }
-
-  public function write($buf) {
-    $this->wBuf_ .= $buf;
-    if (TStringFuncFactory::create()->strlen($this->wBuf_) >= $this->wBufSize_) {
-      $out = $this->wBuf_;
-
-      // Note that we clear the internal wBuf_ prior to the underlying write
-      // to ensure we're in a sane state (i.e. internal buffer cleaned)
-      // if the underlying write throws up an exception
-      $this->wBuf_ = '';
-      $this->transport_->write($out);
-    }
-  }
-
-  public function flush() {
-    if (TStringFuncFactory::create()->strlen($this->wBuf_) > 0) {
-      $this->transport_->write($this->wBuf_);
-      $this->wBuf_ = '';
-    }
-    $this->transport_->flush();
-  }
-
-}
diff --git a/lib/php/src/transport/TFramedTransport.php b/lib/php/src/transport/TFramedTransport.php
index bc759de..e69de29 100644
--- a/lib/php/src/transport/TFramedTransport.php
+++ b/lib/php/src/transport/TFramedTransport.php
@@ -1,179 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Framed transport. Writes and reads data in chunks that are stamped with
- * their length.
- *
- * @package thrift.transport
- */
-class TFramedTransport extends TTransport {
-
-  /**
-   * Underlying transport object.
-   *
-   * @var TTransport
-   */
-  private $transport_;
-
-  /**
-   * Buffer for read data.
-   *
-   * @var string
-   */
-  private $rBuf_;
-
-  /**
-   * Buffer for queued output data
-   *
-   * @var string
-   */
-  private $wBuf_;
-
-  /**
-   * Whether to frame reads
-   *
-   * @var bool
-   */
-  private $read_;
-
-  /**
-   * Whether to frame writes
-   *
-   * @var bool
-   */
-  private $write_;
-
-  /**
-   * Constructor.
-   *
-   * @param TTransport $transport Underlying transport
-   */
-  public function __construct($transport=null, $read=true, $write=true) {
-    $this->transport_ = $transport;
-    $this->read_ = $read;
-    $this->write_ = $write;
-  }
-
-  public function isOpen() {
-    return $this->transport_->isOpen();
-  }
-
-  public function open() {
-    $this->transport_->open();
-  }
-
-  public function close() {
-    $this->transport_->close();
-  }
-
-  /**
-   * Reads from the buffer. When more data is required reads another entire
-   * chunk and serves future reads out of that.
-   *
-   * @param int $len How much data
-   */
-  public function read($len) {
-    if (!$this->read_) {
-      return $this->transport_->read($len);
-    }
-
-    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
-      $this->readFrame();
-    }
-
-    // Just return full buff
-    if ($len >= TStringFuncFactory::create()->strlen($this->rBuf_)) {
-      $out = $this->rBuf_;
-      $this->rBuf_ = null;
-      return $out;
-    }
-
-    // Return TStringFuncFactory::create()->substr
-    $out = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
-    $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
-    return $out;
-  }
-
-  /**
-   * Put previously read data back into the buffer
-   *
-   * @param string $data data to return
-   */
-  public function putBack($data) {
-    if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) {
-      $this->rBuf_ = $data;
-    } else {
-      $this->rBuf_ = ($data . $this->rBuf_);
-    }
-  }
-
-  /**
-   * Reads a chunk of data into the internal read buffer.
-   */
-  private function readFrame() {
-    $buf = $this->transport_->readAll(4);
-    $val = unpack('N', $buf);
-    $sz = $val[1];
-
-    $this->rBuf_ = $this->transport_->readAll($sz);
-  }
-
-  /**
-   * Writes some data to the pending output buffer.
-   *
-   * @param string $buf The data
-   * @param int    $len Limit of bytes to write
-   */
-  public function write($buf, $len=null) {
-    if (!$this->write_) {
-      return $this->transport_->write($buf, $len);
-    }
-
-    if ($len !== null && $len < TStringFuncFactory::create()->strlen($buf)) {
-      $buf = TStringFuncFactory::create()->substr($buf, 0, $len);
-    }
-    $this->wBuf_ .= $buf;
-  }
-
-  /**
-   * Writes the output buffer to the stream in the format of a 4-byte length
-   * followed by the actual data.
-   */
-  public function flush() {
-    if (!$this->write_ || TStringFuncFactory::create()->strlen($this->wBuf_) == 0) {
-      return $this->transport_->flush();
-    }
-
-    $out = pack('N', TStringFuncFactory::create()->strlen($this->wBuf_));
-    $out .= $this->wBuf_;
-
-    // Note that we clear the internal wBuf_ prior to the underlying write
-    // to ensure we're in a sane state (i.e. internal buffer cleaned)
-    // if the underlying write throws up an exception
-    $this->wBuf_ = '';
-    $this->transport_->write($out);
-    $this->transport_->flush();
-  }
-
-}
diff --git a/lib/php/src/transport/THttpClient.php b/lib/php/src/transport/THttpClient.php
index 118f0d3..e69de29 100644
--- a/lib/php/src/transport/THttpClient.php
+++ b/lib/php/src/transport/THttpClient.php
@@ -1,200 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * HTTP client for Thrift
- *
- * @package thrift.transport
- */
-class THttpClient extends TTransport {
-
-  /**
-   * The host to connect to
-   *
-   * @var string
-   */
-  protected $host_;
-
-  /**
-   * The port to connect on
-   *
-   * @var int
-   */
-  protected $port_;
-
-  /**
-   * The URI to request
-   *
-   * @var string
-   */
-  protected $uri_;
-
-  /**
-   * The scheme to use for the request, i.e. http, https
-   *
-   * @var string
-   */
-  protected $scheme_;
-
-  /**
-   * Buffer for the HTTP request data
-   *
-   * @var string
-   */
-  protected $buf_;
-
-  /**
-   * Input socket stream.
-   *
-   * @var resource
-   */
-  protected $handle_;
-
-  /**
-   * Read timeout
-   *
-   * @var float
-   */
-  protected $timeout_;
-
-  /**
-   * Make a new HTTP client.
-   *
-   * @param string $host
-   * @param int    $port
-   * @param string $uri
-   */
-  public function __construct($host, $port=80, $uri='', $scheme = 'http') {
-    if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri{0} != '/')) {
-      $uri = '/'.$uri;
-    }
-    $this->scheme_ = $scheme;
-    $this->host_ = $host;
-    $this->port_ = $port;
-    $this->uri_ = $uri;
-    $this->buf_ = '';
-    $this->handle_ = null;
-    $this->timeout_ = null;
-  }
-
-  /**
-   * Set read timeout
-   *
-   * @param float $timeout
-   */
-  public function setTimeoutSecs($timeout) {
-    $this->timeout_ = $timeout;
-  }
-
-  /**
-   * Whether this transport is open.
-   *
-   * @return boolean true if open
-   */
-  public function isOpen() {
-    return true;
-  }
-
-  /**
-   * Open the transport for reading/writing
-   *
-   * @throws TTransportException if cannot open
-   */
-  public function open() {}
-
-  /**
-   * Close the transport.
-   */
-  public function close() {
-    if ($this->handle_) {
-      @fclose($this->handle_);
-      $this->handle_ = null;
-    }
-  }
-
-  /**
-   * Read some data into the array.
-   *
-   * @param int    $len How much to read
-   * @return string The data that has been read
-   * @throws TTransportException if cannot read any more data
-   */
-  public function read($len) {
-    $data = @fread($this->handle_, $len);
-    if ($data === FALSE || $data === '') {
-      $md = stream_get_meta_data($this->handle_);
-      if ($md['timed_out']) {
-        throw new TTransportException('THttpClient: timed out reading '.$len.' bytes from '.$this->host_.':'.$this->port_.$this->uri_, TTransportException::TIMED_OUT);
-      } else {
-        throw new TTransportException('THttpClient: Could not read '.$len.' bytes from '.$this->host_.':'.$this->port_.$this->uri_, TTransportException::UNKNOWN);
-      }
-    }
-    return $data;
-  }
-
-  /**
-   * Writes some data into the pending buffer
-   *
-   * @param string $buf  The data to write
-   * @throws TTransportException if writing fails
-   */
-  public function write($buf) {
-    $this->buf_ .= $buf;
-  }
-
-  /**
-   * Opens and sends the actual request over the HTTP connection
-   *
-   * @throws TTransportException if a writing error occurs
-   */
-  public function flush() {
-    // God, PHP really has some esoteric ways of doing simple things.
-    $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
-
-    $headers = array('Host: '.$host,
-                     'Accept: application/x-thrift',
-                     'User-Agent: PHP/THttpClient',
-                     'Content-Type: application/x-thrift',
-                     'Content-Length: '.TStringFuncFactory::create()->strlen($this->buf_));
-
-    $options = array('method' => 'POST',
-                     'header' => implode("\r\n", $headers),
-                     'max_redirects' => 1,
-                     'content' => $this->buf_);
-    if ($this->timeout_ > 0) {
-      $options['timeout'] = $this->timeout_;
-    }
-    $this->buf_ = '';
-
-    $contextid = stream_context_create(array('http' => $options));
-    $this->handle_ = @fopen($this->scheme_.'://'.$host.$this->uri_, 'r', false, $contextid);
-
-    // Connect failed?
-    if ($this->handle_ === FALSE) {
-      $this->handle_ = null;
-      $error = 'THttpClient: Could not connect to '.$host.$this->uri_;
-      throw new TTransportException($error, TTransportException::NOT_OPEN);
-    }
-  }
-
-}
diff --git a/lib/php/src/transport/TMemoryBuffer.php b/lib/php/src/transport/TMemoryBuffer.php
index 13aa9e5..e69de29 100644
--- a/lib/php/src/transport/TMemoryBuffer.php
+++ b/lib/php/src/transport/TMemoryBuffer.php
@@ -1,82 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * A memory buffer is a tranpsort that simply reads from and writes to an
- * in-memory string buffer. Anytime you call write on it, the data is simply
- * placed into a buffer, and anytime you call read, data is read from that
- * buffer.
- *
- * @package thrift.transport
- */
-class TMemoryBuffer extends TTransport {
-
-  /**
-   * Constructor. Optionally pass an initial value
-   * for the buffer.
-   */
-  public function __construct($buf = '') {
-    $this->buf_ = $buf;
-  }
-
-  protected $buf_ = '';
-
-  public function isOpen() {
-    return true;
-  }
-
-  public function open() {}
-
-  public function close() {}
-
-  public function write($buf) {
-    $this->buf_ .= $buf;
-  }
-
-  public function read($len) {
-    if (TStringFuncFactory::create()->strlen($this->buf_) === 0) {
-      throw new TTransportException('TMemoryBuffer: Could not read ' .
-                                    $len . ' bytes from buffer.',
-                                    TTransportException::UNKNOWN);
-    }
-
-    if (TStringFuncFactory::create()->strlen($this->buf_) <= $len) {
-      $ret = $this->buf_;
-      $this->buf_ = '';
-      return $ret;
-    }
-
-    $ret = TStringFuncFactory::create()->substr($this->buf_, 0, $len);
-    $this->buf_ = TStringFuncFactory::create()->substr($this->buf_, $len);
-
-    return $ret;
-  }
-
-  function getBuffer() {
-    return $this->buf_;
-  }
-
-  public function available() {
-    return TStringFuncFactory::create()->strlen($this->buf_);
-  }
-}
diff --git a/lib/php/src/transport/TNullTransport.php b/lib/php/src/transport/TNullTransport.php
index 6e5340d..e69de29 100644
--- a/lib/php/src/transport/TNullTransport.php
+++ b/lib/php/src/transport/TNullTransport.php
@@ -1,46 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Transport that only accepts writes and ignores them.
- * This is useful for measuring the serialized size of structures.
- *
- * @package thrift.transport
- */
-class TNullTransport extends TTransport {
-
-  public function isOpen() {
-    return true;
-  }
-
-  public function open() {}
-
-  public function close() {}
-
-  public function read($len) {
-    throw new TTransportException("Can't read from TNullTransport.");
-  }
-
-  public function write($buf) {}
-
-}
diff --git a/lib/php/src/transport/TPhpStream.php b/lib/php/src/transport/TPhpStream.php
index e16b472..e69de29 100644
--- a/lib/php/src/transport/TPhpStream.php
+++ b/lib/php/src/transport/TPhpStream.php
@@ -1,109 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Php stream transport. Reads to and writes from the php standard streams
- * php://input and php://output
- *
- * @package thrift.transport
- */
-class TPhpStream extends TTransport {
-
-  const MODE_R = 1;
-  const MODE_W = 2;
-
-  private $inStream_ = null;
-
-  private $outStream_ = null;
-
-  private $read_ = false;
-
-  private $write_ = false;
-
-  public function __construct($mode) {
-    $this->read_ = $mode & self::MODE_R;
-    $this->write_ = $mode & self::MODE_W;
-  }
-
-  public function open() {
-    if ($this->read_) {
-      $this->inStream_ = @fopen(self::inStreamName(), 'r');
-      if (!is_resource($this->inStream_)) {
-        throw new TException('TPhpStream: Could not open php://input');
-      }
-    }
-    if ($this->write_) {
-      $this->outStream_ = @fopen('php://output', 'w');
-      if (!is_resource($this->outStream_)) {
-        throw new TException('TPhpStream: Could not open php://output');
-      }
-    }
-  }
-
-  public function close() {
-    if ($this->read_) {
-      @fclose($this->inStream_);
-      $this->inStream_ = null;
-    }
-    if ($this->write_) {
-      @fclose($this->outStream_);
-      $this->outStream_ = null;
-    }
-  }
-
-  public function isOpen() {
-    return
-      (!$this->read_ || is_resource($this->inStream_)) &&
-      (!$this->write_ || is_resource($this->outStream_));
-  }
-
-  public function read($len) {
-    $data = @fread($this->inStream_, $len);
-    if ($data === FALSE || $data === '') {
-      throw new TException('TPhpStream: Could not read '.$len.' bytes');
-    }
-    return $data;
-  }
-
-  public function write($buf) {
-    while (TStringFuncFactory::create()->strlen($buf) > 0) {
-      $got = @fwrite($this->outStream_, $buf);
-      if ($got === 0 || $got === FALSE) {
-        throw new TException('TPhpStream: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes');
-      }
-      $buf = TStringFuncFactory::create()->substr($buf, $got);
-    }
-  }
-
-  public function flush() {
-    @fflush($this->outStream_);
-  }
-
-  private static function inStreamName() {
-    if (php_sapi_name() == 'cli') {
-      return 'php://stdin';
-    }
-    return 'php://input';
-  }
-
-}
diff --git a/lib/php/src/transport/TServerSocket.php b/lib/php/src/transport/TServerSocket.php
index cac12ab..e69de29 100644
--- a/lib/php/src/transport/TServerSocket.php
+++ b/lib/php/src/transport/TServerSocket.php
@@ -1,96 +0,0 @@
-<?php
-
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TServerTransport.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
-
-/**
- * Socket implementation of a server agent.
- *
- * @package thrift.transport
- */
-class TServerSocket extends TServerTransport {
-
-  /**
-   * Handle for the listener socket
-   *
-   * @var resource
-   */
-  private $listener_;
-
-  /**
-   * Port for the listener to listen on
-   *
-   * @var int
-   */
-  private $port_;
-
-  /**
-   * Timeout when listening for a new client
-   *
-   * @var int
-   */
-  private $acceptTimeout_ = 30000;
-
-  /**
-   * Host to listen on
-   *
-   * @var string
-   */
-  private $host_;
-
-  /**
-   * ServerSocket constructor
-   *
-   * @param string $host        Host to listen on
-   * @param int $port           Port to listen on
-   * @return void
-   */
-  public function __construct($host = 'localhost', $port = 9090) {
-    $this->host_ = $host;
-    $this->port_ = $port;
-  }
-
-  /**
-   * Sets the accept timeout
-   *
-   * @param int $acceptTimeout
-   * @return void
-   */
-  public function setAcceptTimeout($acceptTimeout) {
-    $this->acceptTimeout_ = $acceptTimeout;
-  }
-
-  /**
-   * Opens a new socket server handle
-   *
-   * @return void
-   */
-  public function listen() {
-    $this->listener_ = stream_socket_server('tcp://' . $this->host_ . ':' . $this->port_);
-  }
-
-  /**
-   * Closes the socket server handle
-   *
-   * @return void
-   */
-  public function close() {
-    @fclose($this->listener_);
-    $this->listener_ = null;
-  }
-
-  /**
-   * Implementation of accept. If not client is accepted in the given time
-   *
-   * @return TSocket
-   */
-  protected function acceptImpl() {
-    $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0);
-    if(!$handle) return null;
-
-    $socket = new TSocket();
-    $socket->setHandle($handle);
-    
-    return $socket;
-  }
-}
diff --git a/lib/php/src/transport/TServerTransport.php b/lib/php/src/transport/TServerTransport.php
index e92ca77..e69de29 100644
--- a/lib/php/src/transport/TServerTransport.php
+++ b/lib/php/src/transport/TServerTransport.php
@@ -1,50 +0,0 @@
-<?php
-
-/**
- * Generic class for Server agent.
- *
- * @package thrift.transport
- */
-abstract class TServerTransport {
-  /**
-   * List for new clients
-   *
-   * @abstract
-   * @return void
-   */
-  abstract public function listen();
-
-  /**
-   * Close the server
-   *
-   * @abstract
-   * @return void
-   */
-  abstract public function close();
-
-  /**
-   * Subclasses should use this to implement
-   * accept.
-   *
-   * @abstract
-   * @return TTransport
-   */
-  protected abstract function acceptImpl();
-
-  /**
-   * Uses the accept implemtation. If null is returned, an
-   * exception is thrown.
-   *
-   * @throws TTransportException
-   * @return TTransport
-   */
-  public function accept() {
-    $transport = $this->acceptImpl();
-
-    if ($transport == null) {
-      throw new TTransportException("accept() may not return NULL");
-    }
-    
-    return $transport;
-  }
-}
diff --git a/lib/php/src/transport/TSocket.php b/lib/php/src/transport/TSocket.php
index 0203384..e69de29 100644
--- a/lib/php/src/transport/TSocket.php
+++ b/lib/php/src/transport/TSocket.php
@@ -1,320 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Sockets implementation of the TTransport interface.
- *
- * @package thrift.transport
- */
-class TSocket extends TTransport {
-
-  /**
-   * Handle to PHP socket
-   *
-   * @var resource
-   */
-  private $handle_ = null;
-
-  /**
-   * Remote hostname
-   *
-   * @var string
-   */
-  protected $host_ = 'localhost';
-
-  /**
-   * Remote port
-   *
-   * @var int
-   */
-  protected $port_ = '9090';
-
-  /**
-   * Send timeout in seconds.
-   *
-   * Combined with sendTimeoutUsec this is used for send timeouts.
-   *
-   * @var int
-   */
-  private $sendTimeoutSec_ = 0;
-
-  /**
-   * Send timeout in microseconds.
-   *
-   * Combined with sendTimeoutSec this is used for send timeouts.
-   *
-   * @var int
-   */
-  private $sendTimeoutUsec_ = 100000;
-
-  /**
-   * Recv timeout in seconds
-   *
-   * Combined with recvTimeoutUsec this is used for recv timeouts.
-   *
-   * @var int
-   */
-  private $recvTimeoutSec_ = 0;
-
-  /**
-   * Recv timeout in microseconds
-   *
-   * Combined with recvTimeoutSec this is used for recv timeouts.
-   *
-   * @var int
-   */
-  private $recvTimeoutUsec_ = 750000;
-
-  /**
-   * Persistent socket or plain?
-   *
-   * @var bool
-   */
-  protected $persist_ = FALSE;
-
-  /**
-   * Debugging on?
-   *
-   * @var bool
-   */
-  protected $debug_ = FALSE;
-
-  /**
-   * Debug handler
-   *
-   * @var mixed
-   */
-  protected $debugHandler_ = null;
-
-  /**
-   * Socket constructor
-   *
-   * @param string $host         Remote hostname
-   * @param int    $port         Remote port
-   * @param bool   $persist      Whether to use a persistent socket
-   * @param string $debugHandler Function to call for error logging
-   */
-  public function __construct($host='localhost',
-                              $port=9090,
-                              $persist=FALSE,
-                              $debugHandler=null) {
-    $this->host_ = $host;
-    $this->port_ = $port;
-    $this->persist_ = $persist;
-    $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
-  }
-
-  /**
-   * @param resource $handle
-   * @return void
-   */
-  public function setHandle($handle) {
-    $this->handle_ = $handle;
-  }
-
-  /**
-   * Sets the send timeout.
-   *
-   * @param int $timeout  Timeout in milliseconds.
-   */
-  public function setSendTimeout($timeout) {
-    $this->sendTimeoutSec_ = floor($timeout / 1000);
-    $this->sendTimeoutUsec_ =
-            ($timeout - ($this->sendTimeoutSec_ * 1000)) * 1000;
-  }
-
-  /**
-   * Sets the receive timeout.
-   *
-   * @param int $timeout  Timeout in milliseconds.
-   */
-  public function setRecvTimeout($timeout) {
-    $this->recvTimeoutSec_ = floor($timeout / 1000);
-    $this->recvTimeoutUsec_ =
-            ($timeout - ($this->recvTimeoutSec_ * 1000)) * 1000;
-  }
-
-  /**
-   * Sets debugging output on or off
-   *
-   * @param bool $debug
-   */
-  public function setDebug($debug) {
-    $this->debug_ = $debug;
-  }
-
-  /**
-   * Get the host that this socket is connected to
-   *
-   * @return string host
-   */
-  public function getHost() {
-    return $this->host_;
-  }
-
-  /**
-   * Get the remote port that this socket is connected to
-   *
-   * @return int port
-   */
-  public function getPort() {
-    return $this->port_;
-  }
-
-  /**
-   * Tests whether this is open
-   *
-   * @return bool true if the socket is open
-   */
-  public function isOpen() {
-    return is_resource($this->handle_);
-  }
-
-  /**
-   * Connects the socket.
-   */
-  public function open() {
-    if ($this->isOpen()) {
-      throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN);
-    }
-
-    if (empty($this->host_)) {
-      throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN);
-    }
-
-    if ($this->port_ <= 0) {
-      throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN);
-    }
-
-    if ($this->persist_) {
-      $this->handle_ = @pfsockopen($this->host_,
-                                   $this->port_,
-                                   $errno,
-                                   $errstr,
-                                   $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
-    } else {
-      $this->handle_ = @fsockopen($this->host_,
-                                  $this->port_,
-                                  $errno,
-                                  $errstr,
-                                  $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
-    }
-
-    // Connect failed?
-    if ($this->handle_ === FALSE) {
-      $error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
-      if ($this->debug_) {
-        call_user_func($this->debugHandler_, $error);
-      }
-      throw new TException($error);
-    }
-  }
-
-  /**
-   * Closes the socket.
-   */
-  public function close() {
-    if (!$this->persist_) {
-      @fclose($this->handle_);
-      $this->handle_ = null;
-    }
-  }
-
-  /**
-   * Read from the socket at most $len bytes.
-   *
-   * This method will not wait for all the requested data, it will return as
-   * soon as any data is received.
-   *
-   * @param int $len Maximum number of bytes to read.
-   * @return string Binary data
-   */
-  public function read($len) {
-    $null = null;
-    $read = array($this->handle_);
-    $readable = @stream_select($read, $null, $null, $this->recvTimeoutSec_, $this->recvTimeoutUsec_);
-
-    if ($readable > 0) {
-      $data = @stream_socket_recvfrom($this->handle_, $len);
-      if ($data === false) {
-          throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
-                               $this->host_.':'.$this->port_);
-      } elseif($data == '' && feof($this->handle_)) {
-          throw new TTransportException('TSocket read 0 bytes');
-        }
-
-      return $data;
-    } else if ($readable === 0) {
-        throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '.
-                             $this->host_.':'.$this->port_);
-      } else {
-        throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
-                             $this->host_.':'.$this->port_);
-      }
-    }
-
-  /**
-   * Write to the socket.
-   *
-   * @param string $buf The data to write
-   */
-  public function write($buf) {
-    $null = null;
-    $write = array($this->handle_);
-
-    // keep writing until all the data has been written
-    while (TStringFuncFactory::create()->strlen($buf) > 0) {
-      // wait for stream to become available for writing
-      $writable = @stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
-      if ($writable > 0) {
-        // write buffer to stream
-        $written = @stream_socket_sendto($this->handle_, $buf);
-        if ($written === -1 || $written === false) {
-          throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
-                                   $this->host_.':'.$this->port_);
-        }
-        // determine how much of the buffer is left to write
-        $buf = TStringFuncFactory::create()->substr($buf, $written);
-      } else if ($writable === 0) {
-          throw new TTransportException('TSocket: timed out writing '.TStringFuncFactory::create()->strlen($buf).' bytes from '.
-                               $this->host_.':'.$this->port_);
-        } else {
-            throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
-                                 $this->host_.':'.$this->port_);
-        }
-      }
-    }
-
-  /**
-   * Flush output to the socket.
-   *
-   * Since read(), readAll() and write() operate on the sockets directly,
-   * this is a no-op
-   *
-   * If you wish to have flushable buffering behaviour, wrap this TSocket
-   * in a TBufferedTransport.
-   */
-  public function flush() {
-    // no-op
-    }
-  }
diff --git a/lib/php/src/transport/TSocketPool.php b/lib/php/src/transport/TSocketPool.php
index ac46c36..e69de29 100644
--- a/lib/php/src/transport/TSocketPool.php
+++ b/lib/php/src/transport/TSocketPool.php
@@ -1,294 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/** Inherits from Socket */
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
-
-/**
- * This library makes use of APC cache to make hosts as down in a web
- * environment. If you are running from the CLI or on a system without APC
- * installed, then these null functions will step in and act like cache
- * misses.
- */
-if (!function_exists('apc_fetch')) {
-  function apc_fetch($key) { return FALSE; }
-  function apc_store($key, $var, $ttl=0) { return FALSE; }
-}
-
-/**
- * Sockets implementation of the TTransport interface that allows connection
- * to a pool of servers.
- *
- * @package thrift.transport
- */
-class TSocketPool extends TSocket {
-
-  /**
-   * Remote servers. Array of associative arrays with 'host' and 'port' keys
-   */
-  private $servers_ = array();
-
-  /**
-   * How many times to retry each host in connect
-   *
-   * @var int
-   */
-  private $numRetries_ = 1;
-
-  /**
-   * Retry interval in seconds, how long to not try a host if it has been
-   * marked as down.
-   *
-   * @var int
-   */
-  private $retryInterval_ = 60;
-
-  /**
-   * Max consecutive failures before marking a host down.
-   *
-   * @var int
-   */
-  private $maxConsecutiveFailures_ = 1;
-
-  /**
-   * Try hosts in order? or Randomized?
-   *
-   * @var bool
-   */
-  private $randomize_ = TRUE;
-
-  /**
-   * Always try last host, even if marked down?
-   *
-   * @var bool
-   */
-  private $alwaysTryLast_ = TRUE;
-
-  /**
-   * Socket pool constructor
-   *
-   * @param array  $hosts        List of remote hostnames
-   * @param mixed  $ports        Array of remote ports, or a single common port
-   * @param bool   $persist      Whether to use a persistent socket
-   * @param mixed  $debugHandler Function for error logging
-   */
-  public function __construct($hosts=array('localhost'),
-                              $ports=array(9090),
-                              $persist=FALSE,
-                              $debugHandler=null) {
-    parent::__construct(null, 0, $persist, $debugHandler);
-
-    if (!is_array($ports)) {
-      $port = $ports;
-      $ports = array();
-      foreach ($hosts as $key => $val) {
-        $ports[$key] = $port;
-      }
-    }
-
-    foreach ($hosts as $key => $host) {
-      $this->servers_ []= array('host' => $host,
-                                'port' => $ports[$key]);
-    }
-  }
-
-  /**
-   * Add a server to the pool
-   *
-   * This function does not prevent you from adding a duplicate server entry.
-   *
-   * @param string $host hostname or IP
-   * @param int $port port
-   */
-  public function addServer($host, $port) {
-    $this->servers_[] = array('host' => $host, 'port' => $port);
-  }
-
-  /**
-   * Sets how many time to keep retrying a host in the connect function.
-   *
-   * @param int $numRetries
-   */
-  public function setNumRetries($numRetries) {
-    $this->numRetries_ = $numRetries;
-  }
-
-  /**
-   * Sets how long to wait until retrying a host if it was marked down
-   *
-   * @param int $numRetries
-   */
-  public function setRetryInterval($retryInterval) {
-    $this->retryInterval_ = $retryInterval;
-  }
-
-  /**
-   * Sets how many time to keep retrying a host before marking it as down.
-   *
-   * @param int $numRetries
-   */
-  public function setMaxConsecutiveFailures($maxConsecutiveFailures) {
-    $this->maxConsecutiveFailures_ = $maxConsecutiveFailures;
-  }
-
-  /**
-   * Turns randomization in connect order on or off.
-   *
-   * @param bool $randomize
-   */
-  public function setRandomize($randomize) {
-    $this->randomize_ = $randomize;
-  }
-
-  /**
-   * Whether to always try the last server.
-   *
-   * @param bool $alwaysTryLast
-   */
-  public function setAlwaysTryLast($alwaysTryLast) {
-    $this->alwaysTryLast_ = $alwaysTryLast;
-  }
-
-
-  /**
-   * Connects the socket by iterating through all the servers in the pool
-   * and trying to find one that works.
-   */
-  public function open() {
-    // Check if we want order randomization
-    if ($this->randomize_) {
-      shuffle($this->servers_);
-    }
-
-    // Count servers to identify the "last" one
-    $numServers = count($this->servers_);
-
-    for ($i = 0; $i < $numServers; ++$i) {
-
-      // This extracts the $host and $port variables
-      extract($this->servers_[$i]);
-
-      // Check APC cache for a record of this server being down
-      $failtimeKey = 'thrift_failtime:'.$host.':'.$port.'~';
-
-      // Cache miss? Assume it's OK
-      $lastFailtime = apc_fetch($failtimeKey);
-      if ($lastFailtime === FALSE) {
-        $lastFailtime = 0;
-      }
-
-      $retryIntervalPassed = FALSE;
-
-      // Cache hit...make sure enough the retry interval has elapsed
-      if ($lastFailtime > 0) {
-        $elapsed = time() - $lastFailtime;
-        if ($elapsed > $this->retryInterval_) {
-          $retryIntervalPassed = TRUE;
-          if ($this->debug_) {
-            call_user_func($this->debugHandler_,
-                           'TSocketPool: retryInterval '.
-                           '('.$this->retryInterval_.') '.
-                           'has passed for host '.$host.':'.$port);
-          }
-        }
-      }
-
-      // Only connect if not in the middle of a fail interval, OR if this
-      // is the LAST server we are trying, just hammer away on it
-      $isLastServer = FALSE;
-      if ($this->alwaysTryLast_) {
-        $isLastServer = ($i == ($numServers - 1));
-      }
-
-      if (($lastFailtime === 0) ||
-          ($isLastServer) ||
-          ($lastFailtime > 0 && $retryIntervalPassed)) {
-
-        // Set underlying TSocket params to this one
-        $this->host_ = $host;
-        $this->port_ = $port;
-
-        // Try up to numRetries_ connections per server
-        for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) {
-          try {
-            // Use the underlying TSocket open function
-            parent::open();
-
-            // Only clear the failure counts if required to do so
-            if ($lastFailtime > 0) {
-              apc_store($failtimeKey, 0);
-            }
-
-            // Successful connection, return now
-            return;
-
-          } catch (TException $tx) {
-            // Connection failed
-          }
-        }
-
-        // Mark failure of this host in the cache
-        $consecfailsKey = 'thrift_consecfails:'.$host.':'.$port.'~';
-
-        // Ignore cache misses
-        $consecfails = apc_fetch($consecfailsKey);
-        if ($consecfails === FALSE) {
-          $consecfails = 0;
-        }
-
-        // Increment by one
-        $consecfails++;
-
-        // Log and cache this failure
-        if ($consecfails >= $this->maxConsecutiveFailures_) {
-          if ($this->debug_) {
-            call_user_func($this->debugHandler_,
-                           'TSocketPool: marking '.$host.':'.$port.
-                           ' as down for '.$this->retryInterval_.' secs '.
-                           'after '.$consecfails.' failed attempts.');
-          }
-          // Store the failure time
-          apc_store($failtimeKey, time());
-
-          // Clear the count of consecutive failures
-          apc_store($consecfailsKey, 0);
-        } else {
-          apc_store($consecfailsKey, $consecfails);
-        }
-      }
-    }
-
-    // Oh no; we failed them all. The system is totally ill!
-    $error = 'TSocketPool: All hosts in pool are down. ';
-    $hosts = array();
-    foreach ($this->servers_ as $server) {
-      $hosts []= $server['host'].':'.$server['port'];
-    }
-    $hostlist = implode(',', $hosts);
-    $error .= '('.$hostlist.')';
-    if ($this->debug_) {
-      call_user_func($this->debugHandler_, $error);
-    }
-    throw new TException($error);
-  }
-}
diff --git a/lib/php/src/transport/TTransport.php b/lib/php/src/transport/TTransport.php
index f8c8d86..e69de29 100644
--- a/lib/php/src/transport/TTransport.php
+++ b/lib/php/src/transport/TTransport.php
@@ -1,106 +0,0 @@
-<?php
-/*
- * 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.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Transport exceptions
- */
-class TTransportException extends TException {
-
-  const UNKNOWN = 0;
-  const NOT_OPEN = 1;
-  const ALREADY_OPEN = 2;
-  const TIMED_OUT = 3;
-  const END_OF_FILE = 4;
-
-  function __construct($message=null, $code=0) {
-    parent::__construct($message, $code);
-  }
-}
-
-/**
- * Base interface for a transport agent.
- *
- * @package thrift.transport
- */
-abstract class TTransport {
-
-  /**
-   * Whether this transport is open.
-   *
-   * @return boolean true if open
-   */
-  public abstract function isOpen();
-
-  /**
-   * Open the transport for reading/writing
-   *
-   * @throws TTransportException if cannot open
-   */
-  public abstract function open();
-
-  /**
-   * Close the transport.
-   */
-  public abstract function close();
-
-  /**
-   * Read some data into the array.
-   *
-   * @param int    $len How much to read
-   * @return string The data that has been read
-   * @throws TTransportException if cannot read any more data
-   */
-  public abstract function read($len);
-
-  /**
-   * Guarantees that the full amount of data is read.
-   *
-   * @return string The data, of exact length
-   * @throws TTransportException if cannot read data
-   */
-  public function readAll($len) {
-    // return $this->read($len);
-
-    $data = '';
-    $got = 0;
-    while (($got = TStringFuncFactory::create()->strlen($data)) < $len) {
-      $data .= $this->read($len - $got);
-    }
-    return $data;
-  }
-
-  /**
-   * Writes the given data out.
-   *
-   * @param string $buf  The data to write
-   * @throws TTransportException if writing fails
-   */
-  public abstract function write($buf);
-
-  /**
-   * Flushes any pending data out of a buffer
-   *
-   * @throws TTransportException if a writing error occurs
-   */
-  public function flush() {}
-}
diff --git a/lib/php/src/transport/TTransportFactory.php b/lib/php/src/transport/TTransportFactory.php
index ac0a65a..e69de29 100644
--- a/lib/php/src/transport/TTransportFactory.php
+++ b/lib/php/src/transport/TTransportFactory.php
@@ -1,12 +0,0 @@
-<?php
-
-class TTransportFactory {
-  /**
-   * @static
-   * @param TTransport $transport
-   * @return TTransport
-   */
-  public static function getTransport(TTransport $transport) {
-    return $transport;
-  }
-}
diff --git a/lib/php/test/Makefile.am b/lib/php/test/Makefile.am
index a4b71db..3ad7781 100755
--- a/lib/php/test/Makefile.am
+++ b/lib/php/test/Makefile.am
@@ -20,14 +20,14 @@
 THRIFT = $(top_builddir)/compiler/cpp/thrift
 
 stubs: ../../../test/ThriftTest.thrift
-	mkdir -p ../src/packages
-	$(THRIFT) --gen php -r --out ../src/packages ../../../test/ThriftTest.thrift
+	mkdir -p ./packages
+	$(THRIFT) --gen php -r --out ./packages ../../../test/ThriftTest.thrift
 
 if HAVE_PHPUNIT
 check: stubs
-	$(PHPUNIT) --log-junit=phpunit.xml protocol/TestTJSONProtocol.php
+	$(PHPUNIT) --log-junit=phpunit.xml Test/Thrift/Protocol/TestTJSONProtocol.php
 endif
 
 clean-local:
-	$(RM) -r gen-php
+	$(RM) -r ./packages
 
diff --git a/lib/php/test/Test/Thrift/Fixtures.php b/lib/php/test/Test/Thrift/Fixtures.php
new file mode 100644
index 0000000..1b86f59
--- /dev/null
+++ b/lib/php/test/Test/Thrift/Fixtures.php
@@ -0,0 +1,192 @@
+<?php
+
+/*
+ * 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.
+ *
+ * @package thrift.test
+ */
+
+namespace Test\Thrift;
+
+use ThriftTest\Xtruct;
+use ThriftTest\Xtruct2;
+use ThriftTest\Numberz;
+use ThriftTest\Insanity;
+
+class Fixtures
+{
+  public static $testArgs = array();
+
+  public static function populateTestArgs()
+  {
+    self::$testArgs['testString1'] = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, Bahasa Melayu, مازِرونی, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad, Occitan, Иронау, Papiamentu, Deitsch, Norfuk / Pitkern, Polski, پنجابی, پښتو, Português, Runa Simi, Rumantsch, Romani, Română, Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, Bân-lâm-gú, 粵語";
+
+    self::$testArgs['testString2'] =
+      "quote: \\\" backslash:" .
+      " forwardslash-escaped: \\/ " .
+      " backspace: \b formfeed: \f newline: \n return: \r tab: " .
+      " now-all-of-them-together: \"\\\/\b\n\r\t" .
+      " now-a-bunch-of-junk: !@#\$%&()(&%$#{}{}<><><";
+
+    self::$testArgs['testString3'] =
+      "string that ends in double-backslash \\\\";
+
+    self::$testArgs['testDouble'] = 3.1415926535898;
+
+    self::$testArgs['testByte'] = 0x01;
+
+    self::$testArgs['testI32'] = pow( 2, 30 );
+
+    if ( PHP_INT_SIZE == 8 )
+    {
+      self::$testArgs['testI64'] = pow( 2, 60 );
+    }
+    else
+    {
+      self::$testArgs['testI64'] = "1152921504606847000";
+    }
+
+    self::$testArgs['testStruct'] =
+      new Xtruct(
+            array(
+                    'string_thing' => 'worked',
+                    'byte_thing' => 0x01,
+                    'i32_thing' => pow( 2, 30 ),
+                    'i64_thing' => self::$testArgs['testI64']
+                    )
+            );
+
+    self::$testArgs['testNestNested'] =
+      new Xtruct(
+            array(
+                    'string_thing' => 'worked',
+                    'byte_thing' => 0x01,
+                    'i32_thing' => pow( 2, 30 ),
+                    'i64_thing' => self::$testArgs['testI64']
+                    )
+            );
+
+    self::$testArgs['testNest'] =
+      new Xtruct2(
+            array(
+                'byte_thing' => 0x01,
+                'struct_thing' => self::$testArgs['testNestNested'],
+                'i32_thing' => pow( 2, 15 )
+                )
+            );
+
+    self::$testArgs['testMap'] =
+      array(
+            7 => 77,
+            8 => 88,
+            9 => 99
+            );
+
+    self::$testArgs['testStringMap'] =
+      array(
+            "a" => "123",
+            "a b" => "with spaces ",
+            "same" => "same",
+            "0" => "numeric key",
+            "longValue" => self::$testArgs['testString1'],
+            self::$testArgs['testString1'] => "long key"
+            );
+
+    self::$testArgs['testSet'] = array( 1 => true, 5 => true, 6 => true );
+
+    self::$testArgs['testList'] = array( 1, 2, 3 );
+
+    self::$testArgs['testEnum'] = Numberz::ONE;
+
+    self::$testArgs['testTypedef'] = 69;
+
+    self::$testArgs['testMapMapExpectedResult'] =
+      array(
+            4 => array(
+                       1 => 1,
+                       2 => 2,
+                       3 => 3,
+                       4 => 4,
+                       ),
+            -4 => array(
+                        -4 => -4,
+                        -3 => -3,
+                        -2 => -2,
+                        -1 => -1
+                        )
+            );
+
+    // testInsanity ... takes a few steps to set up!
+
+    $xtruct1 =
+      new Xtruct(
+            array(
+                'string_thing' => 'Goodbye4',
+                'byte_thing' => 4,
+                'i32_thing' => 4,
+                'i64_thing' => 4
+                )
+            );
+
+    $xtruct2 =
+      new Xtruct(
+            array(
+                'string_thing' => 'Hello2',
+                'byte_thing' =>2,
+                'i32_thing' => 2,
+                'i64_thing' => 2
+                )
+            );
+
+    $userMap =
+      array(
+            Numberz::FIVE => 5,
+            Numberz::EIGHT => 8
+            );
+
+    $insanity2 =
+      new Insanity(
+            array(
+                'userMap' => $userMap,
+                'xtructs' => array($xtruct1,$xtruct2)
+                )
+            );
+
+    $insanity3 = $insanity2;
+
+    $insanity6 =
+      new Insanity(
+            array(
+                'userMap' => null,
+                'xtructs' => null
+                )
+            );
+
+    self::$testArgs['testInsanityExpectedResult'] =
+      array(
+            "1" => array(
+                         Numberz::TWO => $insanity2,
+                         Numberz::THREE => $insanity3
+                    ),
+            "2" => array(
+                         Numberz::SIX => $insanity6
+                    )
+            );
+
+  }
+}
diff --git a/lib/php/test/Test/Thrift/Protocol/TestTJSONProtocol.php b/lib/php/test/Test/Thrift/Protocol/TestTJSONProtocol.php
new file mode 100644
index 0000000..06c6ab2
--- /dev/null
+++ b/lib/php/test/Test/Thrift/Protocol/TestTJSONProtocol.php
@@ -0,0 +1,561 @@
+<?php
+
+/*
+ * 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.
+ *
+ * @package thrift.test
+ */
+
+namespace test\Thrift\Protocol;
+
+use Thrift\ClassLoader\ThriftClassLoader;
+use Test\Thrift\Fixtures;
+use Thrift\Transport\TMemoryBuffer;
+use Thrift\Protocol\TJSONProtocol;
+
+
+define( 'BUFSIZ', 8192 ); //big enough to read biggest serialized Fixture arg.
+
+require_once __DIR__.'/../../../../lib/Thrift/ClassLoader/ThriftClassLoader.php';
+
+$loader = new ThriftClassLoader();
+$loader->registerNamespace('Thrift', __DIR__ . '/../../../../lib');
+$loader->registerNamespace('Test', __DIR__ . '/../../..');
+$loader->registerDefinition('ThriftTest', __DIR__ . '/../../../packages');
+$loader->register();
+
+/***
+ * This test suite depends on running the compiler against the
+ * standard ThriftTest.thrift file:
+ *
+ * lib/php/test$ ../../../compiler/cpp/thrift --gen php -r \
+ *   --out ./packages ../../../test/ThriftTest.thrift
+ */
+
+class TestTJSONProtocol extends \PHPUnit_Framework_TestCase
+{
+  private $transport;
+  private $protocol;
+
+  public static function setUpBeforeClass()
+  {
+    Fixtures::populateTestArgs();
+    TestTJSONProtocol_Fixtures::populateTestArgsJSON();
+  }
+
+  public function setUp()
+  {
+    $this->transport = new TMemoryBuffer();
+    $this->protocol = new TJSONProtocol($this->transport);
+    $this->transport->open();
+  }
+
+  /***
+   * WRITE TESTS
+   */
+
+  public function testVoid_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testVoid_args();
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testVoid'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testString1_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testString_args();
+    $args->thing = Fixtures::$testArgs['testString1'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testString1'];
+
+    #$this->assertEquals( $expected, $actual );
+  }
+
+  public function testString2_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testString_args();
+    $args->thing = Fixtures::$testArgs['testString2'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testString2'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testDouble_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testDouble_args();
+    $args->thing = Fixtures::$testArgs['testDouble'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testDouble'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testByte_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testByte_args();
+    $args->thing = Fixtures::$testArgs['testByte'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testByte'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testI32_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testI32_args();
+    $args->thing = Fixtures::$testArgs['testI32'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testI32'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testI64_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testI64_args();
+    $args->thing = Fixtures::$testArgs['testI64'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testI64'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testStruct_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testStruct_args();
+    $args->thing = Fixtures::$testArgs['testStruct'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testStruct'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testNest_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testNest_args();
+    $args->thing = Fixtures::$testArgs['testNest'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testNest'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testMap_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testMap_args();
+    $args->thing = Fixtures::$testArgs['testMap'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testMap'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testStringMap_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testStringMap_args();
+    $args->thing = Fixtures::$testArgs['testStringMap'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testStringMap'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testSet_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testSet_args();
+    $args->thing = Fixtures::$testArgs['testSet'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testSet'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testList_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testList_args();
+    $args->thing = Fixtures::$testArgs['testList'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testList'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testEnum_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testEnum_args();
+    $args->thing = Fixtures::$testArgs['testEnum'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testEnum'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testTypedef_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testTypedef_args();
+    $args->thing = Fixtures::$testArgs['testTypedef'];
+
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testTypedef'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  /***
+   * READ TESTS
+   */
+
+  public function testVoid_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testVoid']
+			    );
+    $args = new \ThriftTest\ThriftTest_testVoid_args();
+    $args->read( $this->protocol );
+  }
+
+  public function testString1_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testString1']
+			    );
+    $args = new \ThriftTest\ThriftTest_testString_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testString1'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testString2_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testString2']
+			    );
+    $args = new \ThriftTest\ThriftTest_testString_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testString2'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testString3_Write()
+  {
+    $args = new \ThriftTest\ThriftTest_testString_args();
+    $args->thing = Fixtures::$testArgs['testString3'];
+    $args->write( $this->protocol );
+
+    $actual = $this->transport->read( BUFSIZ );
+    $expected = TestTJSONProtocol_Fixtures::$testArgsJSON['testString3'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testDouble_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testDouble']
+			    );
+    $args = new \ThriftTest\ThriftTest_testDouble_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testDouble'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testByte_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testByte']
+			    );
+    $args = new \ThriftTest\ThriftTest_testByte_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testByte'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testI32_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testI32']
+			    );
+    $args = new \ThriftTest\ThriftTest_testI32_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testI32'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testI64_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testI64']
+			    );
+    $args = new \ThriftTest\ThriftTest_testI64_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testI64'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testStruct_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testStruct']
+			    );
+    $args = new \ThriftTest\ThriftTest_testStruct_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testStruct'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testNest_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testNest']
+			    );
+    $args = new \ThriftTest\ThriftTest_testNest_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testNest'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testMap_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testMap']
+			    );
+    $args = new \ThriftTest\ThriftTest_testMap_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testMap'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testStringMap_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testStringMap']
+			    );
+    $args = new \ThriftTest\ThriftTest_testStringMap_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testStringMap'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testSet_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testSet']
+			    );
+    $args = new \ThriftTest\ThriftTest_testSet_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testSet'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testList_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testList']
+			    );
+    $args = new \ThriftTest\ThriftTest_testList_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testList'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testEnum_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testEnum']
+			    );
+    $args = new \ThriftTest\ThriftTest_testEnum_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testEnum'];
+
+    $this->assertEquals( $expected, $actual );
+
+  }
+
+  public function testTypedef_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testTypedef']
+			    );
+    $args = new \ThriftTest\ThriftTest_testTypedef_args();
+    $args->read( $this->protocol );
+
+    $actual = $args->thing;
+    $expected = Fixtures::$testArgs['testTypedef'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testMapMap_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testMapMap']
+			    );
+    $result = new \ThriftTest\ThriftTest_testMapMap_result();
+    $result->read( $this->protocol );
+
+    $actual = $result->success;
+    $expected = Fixtures::$testArgs['testMapMapExpectedResult'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+  public function testInsanity_Read()
+  {
+    $this->transport->write(
+			    TestTJSONProtocol_Fixtures::$testArgsJSON['testInsanity']
+			    );
+    $result = new \ThriftTest\ThriftTest_testInsanity_result();
+    $result->read( $this->protocol );
+
+    $actual = $result->success;
+    $expected = Fixtures::$testArgs['testInsanityExpectedResult'];
+
+    $this->assertEquals( $expected, $actual );
+  }
+
+}
+
+class TestTJSONProtocol_Fixtures
+{
+  public static $testArgsJSON = array();
+
+  public static function populateTestArgsJSON()
+  {
+    self::$testArgsJSON['testVoid'] = '{}';
+
+    self::$testArgsJSON['testString1'] = '{"1":{"str":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e"}}';
+
+    self::$testArgsJSON['testString2'] = '{"1":{"str":"quote: \\\\\" backslash: forwardslash-escaped: \\\\\/  backspace: \\\\b formfeed: \f newline: \n return: \r tab:  now-all-of-them-together: \"\\\\\\\\\/\\\\b\n\r\t now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><"}}';
+
+    self::$testArgsJSON['testString3'] = '{"1":{"str":"string that ends in double-backslash \\\\\\\\"}}';
+
+    self::$testArgsJSON['testDouble'] = '{"1":{"dbl":3.1415926535898}}';
+
+    self::$testArgsJSON['testByte'] = '{"1":{"i8":1}}';
+
+    self::$testArgsJSON['testI32'] = '{"1":{"i32":1073741824}}';
+
+    self::$testArgsJSON['testI64'] = '{"1":{"i64":1152921504606847000}}';
+
+    self::$testArgsJSON['testStruct'] = '{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}}}';
+
+    self::$testArgsJSON['testNest'] = '{"1":{"rec":{"1":{"i8":1},"2":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}},"3":{"i32":32768}}}}';
+
+    self::$testArgsJSON['testMap'] = '{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}';
+
+    self::$testArgsJSON['testStringMap'] = '{"1":{"map":["str","str",6,{"a":"123","a b":"with spaces ","same":"same","0":"numeric key","longValue":"Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e","Afrikaans, Alemannisch, Aragon\u00e9s, \u0627\u0644\u0639\u0631\u0628\u064a\u0629, \u0645\u0635\u0631\u0649, Asturianu, Aymar aru, Az\u0259rbaycan, \u0411\u0430\u0448\u04a1\u043e\u0440\u0442, Boarisch, \u017demait\u0117\u0161ka, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430), \u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438, Bamanankan, \u09ac\u09be\u0982\u09b2\u09be, Brezhoneg, Bosanski, Catal\u00e0, M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304, \u041d\u043e\u0445\u0447\u0438\u0439\u043d, Cebuano, \u13e3\u13b3\u13a9, \u010cesky, \u0421\u043b\u043e\u0432\u0463\u0301\u043d\u044c\u0441\u043a\u044a \/ \u2c14\u2c0e\u2c11\u2c02\u2c21\u2c10\u2c20\u2c14\u2c0d\u2c1f, \u0427\u04d1\u0432\u0430\u0448\u043b\u0430, Cymraeg, Dansk, Zazaki, \u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0, \u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac, Emili\u00e0n e rumagn\u00f2l, English, Esperanto, Espa\u00f1ol, Eesti, Euskara, \u0641\u0627\u0631\u0633\u06cc, Suomi, V\u00f5ro, F\u00f8royskt, Fran\u00e7ais, Arpetan, Furlan, Frysk, Gaeilge, \u8d1b\u8a9e, G\u00e0idhlig, Galego, Ava\u00f1e\'\u1ebd, \u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0, Gaelg, \u05e2\u05d1\u05e8\u05d9\u05ea, \u0939\u093f\u0928\u094d\u0926\u0940, Fiji Hindi, Hrvatski, Krey\u00f2l ayisyen, Magyar, \u0540\u0561\u0575\u0565\u0580\u0565\u0576, Interlingua, Bahasa Indonesia, Ilokano, Ido, \u00cdslenska, Italiano, \u65e5\u672c\u8a9e, Lojban, Basa Jawa, \u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8, Kongo, Kalaallisut, \u0c95\u0ca8\u0ccd\u0ca8\u0ca1, \ud55c\uad6d\uc5b4, \u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440, Ripoarisch, Kurd\u00ee, \u041a\u043e\u043c\u0438, Kernewek, \u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430, Latina, Ladino, L\u00ebtzebuergesch, Limburgs, Ling\u00e1la, \u0ea5\u0eb2\u0ea7, Lietuvi\u0173, Latvie\u0161u, Basa Banyumasan, Malagasy, \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438, \u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02, \u092e\u0930\u093e\u0920\u0940, Bahasa Melayu, \u0645\u0627\u0632\u0650\u0631\u0648\u0646\u06cc, Nnapulitano, Nedersaksisch, \u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, Nederlands, \u202aNorsk (nynorsk)\u202c, \u202aNorsk (bokm\u00e5l)\u202c, Nouormand, Din\u00e9 bizaad, Occitan, \u0418\u0440\u043e\u043d\u0430\u0443, Papiamentu, Deitsch, Norfuk \/ Pitkern, Polski, \u067e\u0646\u062c\u0627\u0628\u06cc, \u067e\u069a\u062a\u0648, Portugu\u00eas, Runa Simi, Rumantsch, Romani, Rom\u00e2n\u0103, \u0420\u0443\u0441\u0441\u043a\u0438\u0439, \u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430, Sardu, Sicilianu, Scots, S\u00e1megiella, Simple English, Sloven\u010dina, Sloven\u0161\u010dina, \u0421\u0440\u043f\u0441\u043a\u0438 \/ Srpski, Seeltersk, Svenska, Kiswahili, \u0ba4\u0bae\u0bbf\u0bb4\u0bcd, \u0c24\u0c46\u0c32\u0c41\u0c17\u0c41, \u0422\u043e\u04b7\u0438\u043a\u04e3, \u0e44\u0e17\u0e22, T\u00fcrkmen\u00e7e, Tagalog, T\u00fcrk\u00e7e, \u0422\u0430\u0442\u0430\u0440\u0447\u0430\/Tatar\u00e7a, \u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430, \u0627\u0631\u062f\u0648, Ti\u1ebfng Vi\u1ec7t, Volap\u00fck, Walon, Winaray, \u5434\u8bed, isiXhosa, \u05d9\u05d9\u05b4\u05d3\u05d9\u05e9, Yor\u00f9b\u00e1, Ze\u00eauws, \u4e2d\u6587, B\u00e2n-l\u00e2m-g\u00fa, \u7cb5\u8a9e":"long key"}]}}';
+
+    self::$testArgsJSON['testSet'] = '{"1":{"set":["i32",3,1,5,6]}}';
+
+    self::$testArgsJSON['testList'] = '{"1":{"lst":["i32",3,1,2,3]}}';
+
+    self::$testArgsJSON['testEnum'] = '{"1":{"i32":1}}';
+
+    self::$testArgsJSON['testTypedef'] = '{"1":{"i64":69}}';
+
+    self::$testArgsJSON['testMapMap'] = '{"0":{"map":["i32","map",2,{"4":["i32","i32",4,{"1":1,"2":2,"3":3,"4":4}],"-4":["i32","i32",4,{"-4":-4,"-3":-3,"-2":-2,"-1":-1}]}]}}';
+
+    self::$testArgsJSON['testInsanity'] = '{"0":{"map":["i64","map",2,{"1":["i32","rec",2,{"2":{"1":{"map":["i32","i64",2,{"5":5,"8":8}]},"2":{"lst":["rec",2,{"1":{"str":"Goodbye4"},"4":{"i8":4},"9":{"i32":4},"11":{"i64":4}},{"1":{"str":"Hello2"},"4":{"i8":2},"9":{"i32":2},"11":{"i64":2}}]}},"3":{"1":{"map":["i32","i64",2,{"5":5,"8":8}]},"2":{"lst":["rec",2,{"1":{"str":"Goodbye4"},"4":{"i8":4},"9":{"i32":4},"11":{"i64":4}},{"1":{"str":"Hello2"},"4":{"i8":2},"9":{"i32":2},"11":{"i64":2}}]}}}],"2":["i32","rec",1,{"6":{}}]}]}}';
+
+  }
+}