diff --git a/contrib/fb303/java/Constants.java b/contrib/fb303/java/Constants.java
deleted file mode 100644
index 79034b4..0000000
--- a/contrib/fb303/java/Constants.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Autogenerated by Thrift
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package com.facebook.fb303;
-
-import java.util.ArrayList;
-import java.util.AbstractMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import org.apache.thrift.*;
-
-public class Constants {
-
-}
diff --git a/contrib/fb303/java/FacebookService.java b/contrib/fb303/java/FacebookService.java
deleted file mode 100644
index 50d19f8..0000000
--- a/contrib/fb303/java/FacebookService.java
+++ /dev/null
@@ -1,2057 +0,0 @@
-/**
- * Autogenerated by Thrift
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package com.facebook.fb303;
-
-import java.util.ArrayList;
-import java.util.AbstractMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import org.apache.thrift.*;
-
-import org.apache.thrift.protocol.*;
-import org.apache.thrift.transport.*;
-
-public class FacebookService {
-
-  public interface Iface {
-    public String getName() throws TException;
-    public String getVersion() throws TException;
-    public int getStatus() throws TException;
-    public String getStatusDetails() throws TException;
-    public AbstractMap<String,Long> getCounters() throws TException;
-    public long getCounter(String key) throws TException;
-    public void setOption(String key, String value) throws TException;
-    public String getOption(String key) throws TException;
-    public AbstractMap<String,String> getOptions() throws TException;
-    public long aliveSince() throws TException;
-    public org.apache.thrift.reflection.limited.Service getLimitedReflection() throws TException;
-    public void reinitialize() throws TException;
-    public void shutdown() throws TException;
-  }
-
-  public static class Client implements Iface {
-    public Client(TProtocol prot)
-    {
-      this(prot, prot);
-    }
-
-    public Client(TProtocol iprot, TProtocol oprot)
-    {
-      iprot_ = iprot;
-      oprot_ = oprot;
-    }
-
-    protected TProtocol iprot_;
-    protected TProtocol oprot_;
-
-    protected int seqid_;
-
-    public String getName() throws TException
-    {
-      send_getName();
-      return recv_getName();
-    }
-
-    public void send_getName() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getName", TMessageType.CALL, seqid_));
-      getName_args args = new getName_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public String recv_getName() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getName_result result = new getName_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getName failed: unknown result");
-    }
-
-    public String getVersion() throws TException
-    {
-      send_getVersion();
-      return recv_getVersion();
-    }
-
-    public void send_getVersion() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getVersion", TMessageType.CALL, seqid_));
-      getVersion_args args = new getVersion_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public String recv_getVersion() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getVersion_result result = new getVersion_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getVersion failed: unknown result");
-    }
-
-    public int getStatus() throws TException
-    {
-      send_getStatus();
-      return recv_getStatus();
-    }
-
-    public void send_getStatus() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getStatus", TMessageType.CALL, seqid_));
-      getStatus_args args = new getStatus_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public int recv_getStatus() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getStatus_result result = new getStatus_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getStatus failed: unknown result");
-    }
-
-    public String getStatusDetails() throws TException
-    {
-      send_getStatusDetails();
-      return recv_getStatusDetails();
-    }
-
-    public void send_getStatusDetails() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getStatusDetails", TMessageType.CALL, seqid_));
-      getStatusDetails_args args = new getStatusDetails_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public String recv_getStatusDetails() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getStatusDetails_result result = new getStatusDetails_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getStatusDetails failed: unknown result");
-    }
-
-    public AbstractMap<String,Long> getCounters() throws TException
-    {
-      send_getCounters();
-      return recv_getCounters();
-    }
-
-    public void send_getCounters() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getCounters", TMessageType.CALL, seqid_));
-      getCounters_args args = new getCounters_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public AbstractMap<String,Long> recv_getCounters() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getCounters_result result = new getCounters_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getCounters failed: unknown result");
-    }
-
-    public long getCounter(String key) throws TException
-    {
-      send_getCounter(key);
-      return recv_getCounter();
-    }
-
-    public void send_getCounter(String key) throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getCounter", TMessageType.CALL, seqid_));
-      getCounter_args args = new getCounter_args();
-      args.key = key;
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public long recv_getCounter() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getCounter_result result = new getCounter_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getCounter failed: unknown result");
-    }
-
-    public void setOption(String key, String value) throws TException
-    {
-      send_setOption(key, value);
-      recv_setOption();
-    }
-
-    public void send_setOption(String key, String value) throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("setOption", TMessageType.CALL, seqid_));
-      setOption_args args = new setOption_args();
-      args.key = key;
-      args.value = value;
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public void recv_setOption() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      setOption_result result = new setOption_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      return;
-    }
-
-    public String getOption(String key) throws TException
-    {
-      send_getOption(key);
-      return recv_getOption();
-    }
-
-    public void send_getOption(String key) throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getOption", TMessageType.CALL, seqid_));
-      getOption_args args = new getOption_args();
-      args.key = key;
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public String recv_getOption() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getOption_result result = new getOption_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getOption failed: unknown result");
-    }
-
-    public AbstractMap<String,String> getOptions() throws TException
-    {
-      send_getOptions();
-      return recv_getOptions();
-    }
-
-    public void send_getOptions() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getOptions", TMessageType.CALL, seqid_));
-      getOptions_args args = new getOptions_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public AbstractMap<String,String> recv_getOptions() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getOptions_result result = new getOptions_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getOptions failed: unknown result");
-    }
-
-    public long aliveSince() throws TException
-    {
-      send_aliveSince();
-      return recv_aliveSince();
-    }
-
-    public void send_aliveSince() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("aliveSince", TMessageType.CALL, seqid_));
-      aliveSince_args args = new aliveSince_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public long recv_aliveSince() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      aliveSince_result result = new aliveSince_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "aliveSince failed: unknown result");
-    }
-
-    public org.apache.thrift.reflection.limited.Service getLimitedReflection() throws TException
-    {
-      send_getLimitedReflection();
-      return recv_getLimitedReflection();
-    }
-
-    public void send_getLimitedReflection() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("getLimitedReflection", TMessageType.CALL, seqid_));
-      getLimitedReflection_args args = new getLimitedReflection_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public org.apache.thrift.reflection.limited.Service recv_getLimitedReflection() throws TException
-    {
-      TMessage msg = iprot_.readMessageBegin();
-      if (msg.type == TMessageType.EXCEPTION) {
-        TApplicationException x = TApplicationException.read(iprot_);
-        iprot_.readMessageEnd();
-        throw x;
-      }
-      getLimitedReflection_result result = new getLimitedReflection_result();
-      result.read(iprot_);
-      iprot_.readMessageEnd();
-      if (result.__isset.success) {
-        return result.success;
-      }
-      throw new TApplicationException(TApplicationException.MISSING_RESULT, "getLimitedReflection failed: unknown result");
-    }
-
-    public void reinitialize() throws TException
-    {
-      send_reinitialize();
-    }
-
-    public void send_reinitialize() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("reinitialize", TMessageType.CALL, seqid_));
-      reinitialize_args args = new reinitialize_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-    public void shutdown() throws TException
-    {
-      send_shutdown();
-    }
-
-    public void send_shutdown() throws TException
-    {
-      oprot_.writeMessageBegin(new TMessage("shutdown", TMessageType.CALL, seqid_));
-      shutdown_args args = new shutdown_args();
-      args.write(oprot_);
-      oprot_.writeMessageEnd();
-      oprot_.getTransport().flush();
-    }
-
-  }
-  public static class Processor implements TProcessor {
-    public Processor(Iface iface)
-    {
-      iface_ = iface;
-      processMap_.put("getName", new getName());
-      processMap_.put("getVersion", new getVersion());
-      processMap_.put("getStatus", new getStatus());
-      processMap_.put("getStatusDetails", new getStatusDetails());
-      processMap_.put("getCounters", new getCounters());
-      processMap_.put("getCounter", new getCounter());
-      processMap_.put("setOption", new setOption());
-      processMap_.put("getOption", new getOption());
-      processMap_.put("getOptions", new getOptions());
-      processMap_.put("aliveSince", new aliveSince());
-      processMap_.put("getLimitedReflection", new getLimitedReflection());
-      processMap_.put("reinitialize", new reinitialize());
-      processMap_.put("shutdown", new shutdown());
-    }
-
-    protected static interface ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException;
-    }
-
-    private Iface iface_;
-    protected final HashMap<String,ProcessFunction> processMap_ = new HashMap<String,ProcessFunction>();
-
-    public boolean process(TProtocol iprot, TProtocol oprot) throws TException
-    {
-      TMessage msg = iprot.readMessageBegin();
-      ProcessFunction fn = processMap_.get(msg.name);
-      if (fn == null) {
-        TProtocolUtil.skip(iprot, TType.STRUCT);
-        iprot.readMessageEnd();
-        TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "Invalid method name: '"+msg.name+"'");
-        oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));
-        x.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-        return true;
-      }
-      fn.process(msg.seqid, iprot, oprot);
-      return true;
-    }
-
-    private class getName implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getName_args args = new getName_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getName_result result = new getName_result();
-        result.success = iface_.getName();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getName", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getVersion implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getVersion_args args = new getVersion_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getVersion_result result = new getVersion_result();
-        result.success = iface_.getVersion();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getVersion", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getStatus implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getStatus_args args = new getStatus_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getStatus_result result = new getStatus_result();
-        result.success = iface_.getStatus();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getStatus", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getStatusDetails implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getStatusDetails_args args = new getStatusDetails_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getStatusDetails_result result = new getStatusDetails_result();
-        result.success = iface_.getStatusDetails();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getStatusDetails", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getCounters implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getCounters_args args = new getCounters_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getCounters_result result = new getCounters_result();
-        result.success = iface_.getCounters();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getCounters", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getCounter implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getCounter_args args = new getCounter_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getCounter_result result = new getCounter_result();
-        result.success = iface_.getCounter(args.key);
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getCounter", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class setOption implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        setOption_args args = new setOption_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        setOption_result result = new setOption_result();
-        iface_.setOption(args.key, args.value);
-        oprot.writeMessageBegin(new TMessage("setOption", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getOption implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getOption_args args = new getOption_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getOption_result result = new getOption_result();
-        result.success = iface_.getOption(args.key);
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getOption", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getOptions implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getOptions_args args = new getOptions_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getOptions_result result = new getOptions_result();
-        result.success = iface_.getOptions();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getOptions", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class aliveSince implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        aliveSince_args args = new aliveSince_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        aliveSince_result result = new aliveSince_result();
-        result.success = iface_.aliveSince();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("aliveSince", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class getLimitedReflection implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        getLimitedReflection_args args = new getLimitedReflection_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        getLimitedReflection_result result = new getLimitedReflection_result();
-        result.success = iface_.getLimitedReflection();
-        result.__isset.success = true;
-        oprot.writeMessageBegin(new TMessage("getLimitedReflection", TMessageType.REPLY, seqid));
-        result.write(oprot);
-        oprot.writeMessageEnd();
-        oprot.getTransport().flush();
-      }
-
-    }
-
-    private class reinitialize implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        reinitialize_args args = new reinitialize_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        iface_.reinitialize();
-        return;
-      }
-    }
-
-    private class shutdown implements ProcessFunction {
-      public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException
-      {
-        shutdown_args args = new shutdown_args();
-        args.read(iprot);
-        iprot.readMessageEnd();
-        iface_.shutdown();
-        return;
-      }
-    }
-
-  }
-
-  public static class getName_args   {
-    public getName_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getName_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getName_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getName_result   {
-    public String success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getName_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.STRING) {
-              this.success = iprot.readString();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getName_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.STRING;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          oprot.writeString(this.success);
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getName_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getVersion_args   {
-    public getVersion_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getVersion_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getVersion_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getVersion_result   {
-    public String success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getVersion_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.STRING) {
-              this.success = iprot.readString();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getVersion_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.STRING;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          oprot.writeString(this.success);
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getVersion_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getStatus_args   {
-    public getStatus_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getStatus_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getStatus_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getStatus_result   {
-    public int success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getStatus_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.I32) {
-              this.success = iprot.readI32();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getStatus_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        field.name = "success";
-        field.type = TType.I32;
-        field.id = 0;
-        oprot.writeFieldBegin(field);
-        oprot.writeI32(this.success);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getStatus_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getStatusDetails_args   {
-    public getStatusDetails_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getStatusDetails_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getStatusDetails_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getStatusDetails_result   {
-    public String success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getStatusDetails_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.STRING) {
-              this.success = iprot.readString();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getStatusDetails_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.STRING;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          oprot.writeString(this.success);
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getStatusDetails_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getCounters_args   {
-    public getCounters_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getCounters_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getCounters_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getCounters_result   {
-    public AbstractMap<String,Long> success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getCounters_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.MAP) {
-              {
-                TMap _map0 = iprot.readMapBegin();
-                this.success = new HashMap<String,Long>(2*_map0.size);
-                for (int _i1 = 0; _i1 < _map0.size; ++_i1)
-                {
-                  String _key2;
-                  long _val3;
-                  _key2 = iprot.readString();
-                  _val3 = iprot.readI64();
-                  this.success.put(_key2, _val3);
-                }
-                iprot.readMapEnd();
-              }
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getCounters_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.MAP;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          {
-            oprot.writeMapBegin(new TMap(TType.STRING, TType.I64, this.success.size()));
-            for (String _iter4 : this.success.keySet())            {
-              oprot.writeString(_iter4);
-              oprot.writeI64(this.success.get(_iter4));
-              oprot.writeMapEnd();
-            }
-          }
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getCounters_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getCounter_args   {
-    public String key;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean key = false;
-    }
-
-    public getCounter_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 1:
-            if (field.type == TType.STRING) {
-              this.key = iprot.readString();
-              this.__isset.key = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getCounter_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      if (this.key != null) {
-        field.name = "key";
-        field.type = TType.STRING;
-        field.id = 1;
-        oprot.writeFieldBegin(field);
-        oprot.writeString(this.key);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getCounter_args(");
-      sb.append("key:");
-      sb.append(this.key);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getCounter_result   {
-    public long success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getCounter_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.I64) {
-              this.success = iprot.readI64();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getCounter_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        field.name = "success";
-        field.type = TType.I64;
-        field.id = 0;
-        oprot.writeFieldBegin(field);
-        oprot.writeI64(this.success);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getCounter_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class setOption_args   {
-    public String key;
-    public String value;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean key = false;
-      public boolean value = false;
-    }
-
-    public setOption_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 1:
-            if (field.type == TType.STRING) {
-              this.key = iprot.readString();
-              this.__isset.key = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          case 2:
-            if (field.type == TType.STRING) {
-              this.value = iprot.readString();
-              this.__isset.value = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("setOption_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      if (this.key != null) {
-        field.name = "key";
-        field.type = TType.STRING;
-        field.id = 1;
-        oprot.writeFieldBegin(field);
-        oprot.writeString(this.key);
-        oprot.writeFieldEnd();
-      }
-      if (this.value != null) {
-        field.name = "value";
-        field.type = TType.STRING;
-        field.id = 2;
-        oprot.writeFieldBegin(field);
-        oprot.writeString(this.value);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setOption_args(");
-      sb.append("key:");
-      sb.append(this.key);
-      sb.append(",value:");
-      sb.append(this.value);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class setOption_result   {
-    public setOption_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("setOption_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setOption_result(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getOption_args   {
-    public String key;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean key = false;
-    }
-
-    public getOption_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 1:
-            if (field.type == TType.STRING) {
-              this.key = iprot.readString();
-              this.__isset.key = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getOption_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      if (this.key != null) {
-        field.name = "key";
-        field.type = TType.STRING;
-        field.id = 1;
-        oprot.writeFieldBegin(field);
-        oprot.writeString(this.key);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getOption_args(");
-      sb.append("key:");
-      sb.append(this.key);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getOption_result   {
-    public String success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getOption_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.STRING) {
-              this.success = iprot.readString();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getOption_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.STRING;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          oprot.writeString(this.success);
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getOption_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getOptions_args   {
-    public getOptions_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getOptions_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getOptions_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getOptions_result   {
-    public AbstractMap<String,String> success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getOptions_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.MAP) {
-              {
-                TMap _map5 = iprot.readMapBegin();
-                this.success = new HashMap<String,String>(2*_map5.size);
-                for (int _i6 = 0; _i6 < _map5.size; ++_i6)
-                {
-                  String _key7;
-                  String _val8;
-                  _key7 = iprot.readString();
-                  _val8 = iprot.readString();
-                  this.success.put(_key7, _val8);
-                }
-                iprot.readMapEnd();
-              }
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getOptions_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.MAP;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          {
-            oprot.writeMapBegin(new TMap(TType.STRING, TType.STRING, this.success.size()));
-            for (String _iter9 : this.success.keySet())            {
-              oprot.writeString(_iter9);
-              oprot.writeString(this.success.get(_iter9));
-              oprot.writeMapEnd();
-            }
-          }
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getOptions_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class aliveSince_args   {
-    public aliveSince_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("aliveSince_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("aliveSince_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class aliveSince_result   {
-    public long success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public aliveSince_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.I64) {
-              this.success = iprot.readI64();
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("aliveSince_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        field.name = "success";
-        field.type = TType.I64;
-        field.id = 0;
-        oprot.writeFieldBegin(field);
-        oprot.writeI64(this.success);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("aliveSince_result(");
-      sb.append("success:");
-      sb.append(this.success);
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getLimitedReflection_args   {
-    public getLimitedReflection_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getLimitedReflection_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getLimitedReflection_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class getLimitedReflection_result   {
-    public org.apache.thrift.reflection.limited.Service success;
-
-    public final Isset __isset = new Isset();
-    public final class Isset {
-      public boolean success = false;
-    }
-
-    public getLimitedReflection_result() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          case 0:
-            if (field.type == TType.STRUCT) {
-              this.success = new org.apache.thrift.reflection.limited.Service();
-              this.success.read(iprot);
-              this.__isset.success = true;
-            } else { 
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("getLimitedReflection_result");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-
-      if (this.__isset.success) {
-        if (this.success != null) {
-          field.name = "success";
-          field.type = TType.STRUCT;
-          field.id = 0;
-          oprot.writeFieldBegin(field);
-          this.success.write(oprot);
-          oprot.writeFieldEnd();
-        }
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getLimitedReflection_result(");
-      sb.append("success:");
-      sb.append(this.success.toString());
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class reinitialize_args   {
-    public reinitialize_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("reinitialize_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("reinitialize_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-  public static class shutdown_args   {
-    public shutdown_args() {
-    }
-
-    public void read(TProtocol iprot) throws TException {
-      TField field;
-      TStruct struct = iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) { 
-          break;
-        }
-        switch (field.id)
-        {
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-    }
-
-    public void write(TProtocol oprot) throws TException {
-      TStruct struct = new TStruct("shutdown_args");
-      TField field = new TField();
-      oprot.writeStructBegin(struct);
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    public String toString() {
-      StringBuilder sb = new StringBuilder("shutdown_args(");
-      sb.append(")");
-      return sb.toString();
-    }
-
-  }
-
-}
diff --git a/contrib/fb303/java/fb_status.java b/contrib/fb303/java/fb_status.java
deleted file mode 100644
index 4b51b8c..0000000
--- a/contrib/fb303/java/fb_status.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Autogenerated by Thrift
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package com.facebook.fb303;
-
-
-public class fb_status {
-  public static final int DEAD = 0;
-  public static final int STARTING = 1;
-  public static final int ALIVE = 2;
-  public static final int STOPPING = 3;
-  public static final int STOPPED = 4;
-  public static final int WARNING = 5;
-}
diff --git a/contrib/fb303/py/fb303/FacebookBase.py b/contrib/fb303/py/fb303/FacebookBase.py
deleted file mode 100644
index f365517..0000000
--- a/contrib/fb303/py/fb303/FacebookBase.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2006- Facebook
-# Distributed under the Thrift Software License
-#
-# See accompanying file LICENSE or visit the Thrift site at:
-# http://developers.facebook.com/thrift/
-
-import time
-import FacebookService
-import thrift.reflection.limited
-from ttypes import fb_status
-
-class FacebookBase(FacebookService.Iface):
-
-  def __init__(self, name):
-    self.name = name
-    self.alive = int(time.time())
-    self.counters = {}
- 
-  def getName(self, ):
-    return self.name
-
-  def getVersion(self, ):
-    return ''
-
-  def getStatus(self, ):
-    return fb_status.ALIVE
-
-  def getCounters(self):
-    return self.counters
-
-  def resetCounter(self, key):
-    self.counters[key] = 0
-
-  def getCounter(self, key):
-    if self.counters.has_key(key):
-      return self.counters[key]
-    return 0
-
-  def incrementCounter(self, key):
-    self.counters[key] = self.getCounter(key) + 1
-
-  def setOption(self, key, value):
-    pass
-
-  def getOption(self, key):
-    return ""
-
-  def getOptions(self):
-    return {}
-
-  def getOptions(self):
-    return {}
-
-  def aliveSince(self):
-    return self.alive
-
-  def getCpuProfile(self, duration):
-    return ""
-
-  def getLimitedReflection(self):
-    return thrift.reflection.limited.Service()
-
-  def reinitialize(self):
-    pass
-
-  def shutdown(self):
-    pass
diff --git a/contrib/fb303/py/fb303/FacebookService-remote b/contrib/fb303/py/fb303/FacebookService-remote
deleted file mode 100755
index af985be..0000000
--- a/contrib/fb303/py/fb303/FacebookService-remote
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env python
-#
-# Autogenerated by Thrift
-#
-# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
-#
-
-import sys
-import pprint
-from urlparse import urlparse
-from thrift.transport import TTransport
-from thrift.transport import TSocket
-from thrift.transport import THttpClient
-from thrift.protocol import TBinaryProtocol
-
-import FacebookService
-from ttypes import *
-
-if len(sys.argv) <= 1 or sys.argv[1] == '--help':
-  print ''
-  print 'Usage: ' + sys.argv[0] + ' [-h host:port] [-u url] [-f[ramed]] function [arg1 [arg2...]]'
-  print ''
-  print 'Functions:'
-  print '  string getName()'
-  print '  string getVersion()'
-  print '  fb_status getStatus()'
-  print '  string getStatusDetails()'
-  print '   getCounters()'
-  print '  i64 getCounter(string key)'
-  print '  void setOption(string key, string value)'
-  print '  string getOption(string key)'
-  print '   getOptions()'
-  print '  i64 aliveSince()'
-  print '  Service getLimitedReflection()'
-  print '  void reinitialize()'
-  print '  void shutdown()'
-  print ''
-  sys.exit(0)
-
-pp = pprint.PrettyPrinter(indent = 2)
-host = 'localhost'
-port = 9090
-uri = ''
-framed = False
-http = False
-argi = 1
-
-if sys.argv[argi] == '-h':
-  parts = sys.argv[argi+1].split(':') 
-  host = parts[0]
-  port = int(parts[1])
-  argi += 2
-
-if sys.argv[argi] == '-u':
-  url = urlparse(sys.argv[argi+1])
-  parts = url[1].split(':') 
-  host = parts[0]
-  if len(parts) > 1:
-    port = int(parts[1])
-  else:
-    port = 80
-  uri = url[2]
-  http = True
-  argi += 2
-
-if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':
-  framed = True
-  argi += 1
-
-cmd = sys.argv[argi]
-args = sys.argv[argi+1:]
-
-if http:
-  transport = THttpClient.THttpClient(host, port, uri)
-else:
-  socket = TSocket.TSocket(host, port)
-  if framed:
-    transport = TTransport.TFramedTransport(socket)
-  else:
-    transport = TTransport.TBufferedTransport(socket)
-protocol = TBinaryProtocol.TBinaryProtocol(transport)
-client = FacebookService.Client(protocol)
-transport.open()
-
-if cmd == 'getName':
-  if len(args) != 0:
-    print 'getName requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getName())
-
-elif cmd == 'getVersion':
-  if len(args) != 0:
-    print 'getVersion requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getVersion())
-
-elif cmd == 'getStatus':
-  if len(args) != 0:
-    print 'getStatus requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getStatus())
-
-elif cmd == 'getStatusDetails':
-  if len(args) != 0:
-    print 'getStatusDetails requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getStatusDetails())
-
-elif cmd == 'getCounters':
-  if len(args) != 0:
-    print 'getCounters requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getCounters())
-
-elif cmd == 'getCounter':
-  if len(args) != 1:
-    print 'getCounter requires 1 args'
-    sys.exit(1)
-  pp.pprint(client.getCounter(args[0],))
-
-elif cmd == 'setOption':
-  if len(args) != 2:
-    print 'setOption requires 2 args'
-    sys.exit(1)
-  pp.pprint(client.setOption(args[0],args[1],))
-
-elif cmd == 'getOption':
-  if len(args) != 1:
-    print 'getOption requires 1 args'
-    sys.exit(1)
-  pp.pprint(client.getOption(args[0],))
-
-elif cmd == 'getOptions':
-  if len(args) != 0:
-    print 'getOptions requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getOptions())
-
-elif cmd == 'aliveSince':
-  if len(args) != 0:
-    print 'aliveSince requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.aliveSince())
-
-elif cmd == 'getLimitedReflection':
-  if len(args) != 0:
-    print 'getLimitedReflection requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.getLimitedReflection())
-
-elif cmd == 'reinitialize':
-  if len(args) != 0:
-    print 'reinitialize requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.reinitialize())
-
-elif cmd == 'shutdown':
-  if len(args) != 0:
-    print 'shutdown requires 0 args'
-    sys.exit(1)
-  pp.pprint(client.shutdown())
-
-transport.close()
diff --git a/contrib/fb303/py/fb303/FacebookService.py b/contrib/fb303/py/fb303/FacebookService.py
deleted file mode 100644
index ddf7d33..0000000
--- a/contrib/fb303/py/fb303/FacebookService.py
+++ /dev/null
@@ -1,1831 +0,0 @@
-#
-# Autogenerated by Thrift
-#
-# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
-#
-
-from thrift.Thrift import *
-from ttypes import *
-from thrift.Thrift import TProcessor
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-try:
-  from thrift.protocol import fastbinary
-except:
-  fastbinary = None
-
-
-class Iface:
-  def getName(self, ):
-    pass
-
-  def getVersion(self, ):
-    pass
-
-  def getStatus(self, ):
-    pass
-
-  def getStatusDetails(self, ):
-    pass
-
-  def getCounters(self, ):
-    pass
-
-  def getCounter(self, key):
-    pass
-
-  def setOption(self, key, value):
-    pass
-
-  def getOption(self, key):
-    pass
-
-  def getOptions(self, ):
-    pass
-
-  def aliveSince(self, ):
-    pass
-
-  def getLimitedReflection(self, ):
-    pass
-
-  def reinitialize(self, ):
-    pass
-
-  def shutdown(self, ):
-    pass
-
-
-class Client(Iface):
-  def __init__(self, iprot, oprot=None):
-    self._iprot = self._oprot = iprot
-    if oprot != None:
-      self._oprot = oprot
-    self._seqid = 0
-
-  def getName(self, ):
-    self.send_getName()
-    return self.recv_getName()
-
-  def send_getName(self, ):
-    self._oprot.writeMessageBegin('getName', TMessageType.CALL, self._seqid)
-    args = getName_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getName(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getName_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getName failed: unknown result");
-
-  def getVersion(self, ):
-    self.send_getVersion()
-    return self.recv_getVersion()
-
-  def send_getVersion(self, ):
-    self._oprot.writeMessageBegin('getVersion', TMessageType.CALL, self._seqid)
-    args = getVersion_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getVersion(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getVersion_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getVersion failed: unknown result");
-
-  def getStatus(self, ):
-    self.send_getStatus()
-    return self.recv_getStatus()
-
-  def send_getStatus(self, ):
-    self._oprot.writeMessageBegin('getStatus', TMessageType.CALL, self._seqid)
-    args = getStatus_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getStatus(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getStatus_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getStatus failed: unknown result");
-
-  def getStatusDetails(self, ):
-    self.send_getStatusDetails()
-    return self.recv_getStatusDetails()
-
-  def send_getStatusDetails(self, ):
-    self._oprot.writeMessageBegin('getStatusDetails', TMessageType.CALL, self._seqid)
-    args = getStatusDetails_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getStatusDetails(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getStatusDetails_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getStatusDetails failed: unknown result");
-
-  def getCounters(self, ):
-    self.send_getCounters()
-    return self.recv_getCounters()
-
-  def send_getCounters(self, ):
-    self._oprot.writeMessageBegin('getCounters', TMessageType.CALL, self._seqid)
-    args = getCounters_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getCounters(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getCounters_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getCounters failed: unknown result");
-
-  def getCounter(self, key):
-    self.send_getCounter(key)
-    return self.recv_getCounter()
-
-  def send_getCounter(self, key):
-    self._oprot.writeMessageBegin('getCounter', TMessageType.CALL, self._seqid)
-    args = getCounter_args()
-    args.key = key
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getCounter(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getCounter_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getCounter failed: unknown result");
-
-  def setOption(self, key, value):
-    self.send_setOption(key, value)
-    self.recv_setOption()
-
-  def send_setOption(self, key, value):
-    self._oprot.writeMessageBegin('setOption', TMessageType.CALL, self._seqid)
-    args = setOption_args()
-    args.key = key
-    args.value = value
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_setOption(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = setOption_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    return
-
-  def getOption(self, key):
-    self.send_getOption(key)
-    return self.recv_getOption()
-
-  def send_getOption(self, key):
-    self._oprot.writeMessageBegin('getOption', TMessageType.CALL, self._seqid)
-    args = getOption_args()
-    args.key = key
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getOption(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getOption_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getOption failed: unknown result");
-
-  def getOptions(self, ):
-    self.send_getOptions()
-    return self.recv_getOptions()
-
-  def send_getOptions(self, ):
-    self._oprot.writeMessageBegin('getOptions', TMessageType.CALL, self._seqid)
-    args = getOptions_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getOptions(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getOptions_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getOptions failed: unknown result");
-
-  def aliveSince(self, ):
-    self.send_aliveSince()
-    return self.recv_aliveSince()
-
-  def send_aliveSince(self, ):
-    self._oprot.writeMessageBegin('aliveSince', TMessageType.CALL, self._seqid)
-    args = aliveSince_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_aliveSince(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = aliveSince_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "aliveSince failed: unknown result");
-
-  def getLimitedReflection(self, ):
-    self.send_getLimitedReflection()
-    return self.recv_getLimitedReflection()
-
-  def send_getLimitedReflection(self, ):
-    self._oprot.writeMessageBegin('getLimitedReflection', TMessageType.CALL, self._seqid)
-    args = getLimitedReflection_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-  def recv_getLimitedReflection(self, ):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
-      raise x
-    result = getLimitedReflection_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
-    if result.success != None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getLimitedReflection failed: unknown result");
-
-  def reinitialize(self, ):
-    self.send_reinitialize()
-
-  def send_reinitialize(self, ):
-    self._oprot.writeMessageBegin('reinitialize', TMessageType.CALL, self._seqid)
-    args = reinitialize_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-  def shutdown(self, ):
-    self.send_shutdown()
-
-  def send_shutdown(self, ):
-    self._oprot.writeMessageBegin('shutdown', TMessageType.CALL, self._seqid)
-    args = shutdown_args()
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-
-class Processor(Iface, TProcessor):
-  def __init__(self, handler):
-    self._handler = handler
-    self._processMap = {}
-    self._processMap["getName"] = Processor.process_getName
-    self._processMap["getVersion"] = Processor.process_getVersion
-    self._processMap["getStatus"] = Processor.process_getStatus
-    self._processMap["getStatusDetails"] = Processor.process_getStatusDetails
-    self._processMap["getCounters"] = Processor.process_getCounters
-    self._processMap["getCounter"] = Processor.process_getCounter
-    self._processMap["setOption"] = Processor.process_setOption
-    self._processMap["getOption"] = Processor.process_getOption
-    self._processMap["getOptions"] = Processor.process_getOptions
-    self._processMap["aliveSince"] = Processor.process_aliveSince
-    self._processMap["getLimitedReflection"] = Processor.process_getLimitedReflection
-    self._processMap["reinitialize"] = Processor.process_reinitialize
-    self._processMap["shutdown"] = Processor.process_shutdown
-
-  def process(self, iprot, oprot):
-    (name, type, seqid) = iprot.readMessageBegin()
-    if name not in self._processMap:
-      iprot.skip(TType.STRUCT)
-      iprot.readMessageEnd()
-      x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
-      oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
-      x.write(oprot)
-      oprot.writeMessageEnd()
-      oprot.trans.flush()
-      return
-    else:
-      self._processMap[name](self, seqid, iprot, oprot)
-    return True
-
-  def process_getName(self, seqid, iprot, oprot):
-    args = getName_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getName_result()
-    result.success = self._handler.getName()
-    oprot.writeMessageBegin("getName", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getVersion(self, seqid, iprot, oprot):
-    args = getVersion_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getVersion_result()
-    result.success = self._handler.getVersion()
-    oprot.writeMessageBegin("getVersion", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getStatus(self, seqid, iprot, oprot):
-    args = getStatus_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getStatus_result()
-    result.success = self._handler.getStatus()
-    oprot.writeMessageBegin("getStatus", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getStatusDetails(self, seqid, iprot, oprot):
-    args = getStatusDetails_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getStatusDetails_result()
-    result.success = self._handler.getStatusDetails()
-    oprot.writeMessageBegin("getStatusDetails", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getCounters(self, seqid, iprot, oprot):
-    args = getCounters_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getCounters_result()
-    result.success = self._handler.getCounters()
-    oprot.writeMessageBegin("getCounters", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getCounter(self, seqid, iprot, oprot):
-    args = getCounter_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getCounter_result()
-    result.success = self._handler.getCounter(args.key)
-    oprot.writeMessageBegin("getCounter", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_setOption(self, seqid, iprot, oprot):
-    args = setOption_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = setOption_result()
-    self._handler.setOption(args.key, args.value)
-    oprot.writeMessageBegin("setOption", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getOption(self, seqid, iprot, oprot):
-    args = getOption_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getOption_result()
-    result.success = self._handler.getOption(args.key)
-    oprot.writeMessageBegin("getOption", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getOptions(self, seqid, iprot, oprot):
-    args = getOptions_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getOptions_result()
-    result.success = self._handler.getOptions()
-    oprot.writeMessageBegin("getOptions", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_aliveSince(self, seqid, iprot, oprot):
-    args = aliveSince_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = aliveSince_result()
-    result.success = self._handler.aliveSince()
-    oprot.writeMessageBegin("aliveSince", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getLimitedReflection(self, seqid, iprot, oprot):
-    args = getLimitedReflection_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getLimitedReflection_result()
-    result.success = self._handler.getLimitedReflection()
-    oprot.writeMessageBegin("getLimitedReflection", TMessageType.REPLY, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_reinitialize(self, seqid, iprot, oprot):
-    args = reinitialize_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    self._handler.reinitialize()
-    return
-
-  def process_shutdown(self, seqid, iprot, oprot):
-    args = shutdown_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    self._handler.shutdown()
-    return
-
-
-# HELPER FUNCTIONS AND STRUCTURES
-
-class getName_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getName_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getName_result:
-
-  thrift_spec = (
-    (0, TType.STRING, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.STRING:
-          self.success = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getName_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getVersion_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getVersion_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getVersion_result:
-
-  thrift_spec = (
-    (0, TType.STRING, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.STRING:
-          self.success = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getVersion_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getStatus_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getStatus_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getStatus_result:
-
-  thrift_spec = (
-    (0, TType.I32, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.I32:
-          self.success = iprot.readI32();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getStatus_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.I32, 0)
-      oprot.writeI32(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getStatusDetails_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getStatusDetails_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getStatusDetails_result:
-
-  thrift_spec = (
-    (0, TType.STRING, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.STRING:
-          self.success = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getStatusDetails_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getCounters_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getCounters_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getCounters_result:
-
-  thrift_spec = (
-    (0, TType.MAP, 'success', (TType.STRING,None,TType.I64,None), None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.MAP:
-          self.success = {}
-          (_ktype1, _vtype2, _size0 ) = iprot.readMapBegin() 
-          for _i4 in xrange(_size0):
-            _key5 = iprot.readString();
-            _val6 = iprot.readI64();
-            self.success[_key5] = _val6
-          iprot.readMapEnd()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getCounters_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.I64, len(self.success))
-      for kiter7,viter8 in self.success.items():
-        oprot.writeString(kiter7)
-        oprot.writeI64(viter8)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getCounter_args:
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'key', None, None, ), # 1
-  )
-
-  def __init__(self, d=None):
-    self.key = None
-    if isinstance(d, dict):
-      if 'key' in d:
-        self.key = d['key']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 1:
-        if ftype == TType.STRING:
-          self.key = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getCounter_args')
-    if self.key != None:
-      oprot.writeFieldBegin('key', TType.STRING, 1)
-      oprot.writeString(self.key)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getCounter_result:
-
-  thrift_spec = (
-    (0, TType.I64, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.I64:
-          self.success = iprot.readI64();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getCounter_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.I64, 0)
-      oprot.writeI64(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class setOption_args:
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'key', None, None, ), # 1
-    (2, TType.STRING, 'value', None, None, ), # 2
-  )
-
-  def __init__(self, d=None):
-    self.key = None
-    self.value = None
-    if isinstance(d, dict):
-      if 'key' in d:
-        self.key = d['key']
-      if 'value' in d:
-        self.value = d['value']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 1:
-        if ftype == TType.STRING:
-          self.key = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.value = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('setOption_args')
-    if self.key != None:
-      oprot.writeFieldBegin('key', TType.STRING, 1)
-      oprot.writeString(self.key)
-      oprot.writeFieldEnd()
-    if self.value != None:
-      oprot.writeFieldBegin('value', TType.STRING, 2)
-      oprot.writeString(self.value)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class setOption_result:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('setOption_result')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getOption_args:
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'key', None, None, ), # 1
-  )
-
-  def __init__(self, d=None):
-    self.key = None
-    if isinstance(d, dict):
-      if 'key' in d:
-        self.key = d['key']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 1:
-        if ftype == TType.STRING:
-          self.key = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getOption_args')
-    if self.key != None:
-      oprot.writeFieldBegin('key', TType.STRING, 1)
-      oprot.writeString(self.key)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getOption_result:
-
-  thrift_spec = (
-    (0, TType.STRING, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.STRING:
-          self.success = iprot.readString();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getOption_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getOptions_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getOptions_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getOptions_result:
-
-  thrift_spec = (
-    (0, TType.MAP, 'success', (TType.STRING,None,TType.STRING,None), None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.MAP:
-          self.success = {}
-          (_ktype10, _vtype11, _size9 ) = iprot.readMapBegin() 
-          for _i13 in xrange(_size9):
-            _key14 = iprot.readString();
-            _val15 = iprot.readString();
-            self.success[_key14] = _val15
-          iprot.readMapEnd()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getOptions_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
-      for kiter16,viter17 in self.success.items():
-        oprot.writeString(kiter16)
-        oprot.writeString(viter17)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class aliveSince_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('aliveSince_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class aliveSince_result:
-
-  thrift_spec = (
-    (0, TType.I64, 'success', None, None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.I64:
-          self.success = iprot.readI64();
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('aliveSince_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.I64, 0)
-      oprot.writeI64(self.success)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getLimitedReflection_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getLimitedReflection_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class getLimitedReflection_result:
-
-  thrift_spec = (
-    (0, TType.STRUCT, 'success', (thrift.reflection.limited.ttypes.Service, thrift.reflection.limited.ttypes.Service.thrift_spec), None, ), # 0
-  )
-
-  def __init__(self, d=None):
-    self.success = None
-    if isinstance(d, dict):
-      if 'success' in d:
-        self.success = d['success']
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      if fid == 0:
-        if ftype == TType.STRUCT:
-          self.success = thrift.reflection.limited.ttypes.Service()
-          self.success.read(iprot)
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('getLimitedReflection_result')
-    if self.success != None:
-      oprot.writeFieldBegin('success', TType.STRUCT, 0)
-      self.success.write(oprot)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class reinitialize_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('reinitialize_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class reinitialize_result:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('reinitialize_result')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class shutdown_args:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('shutdown_args')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-class shutdown_result:
-
-  thrift_spec = (
-  )
-
-  def __init__(self, d=None):
-    pass
-
-  def read(self, iprot):
-    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
-      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
-      return
-    iprot.readStructBegin()
-    while True:
-      (fname, ftype, fid) = iprot.readFieldBegin()
-      if ftype == TType.STOP:
-        break
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
-
-  def write(self, oprot):
-    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
-      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
-      return
-    oprot.writeStructBegin('shutdown_result')
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def __str__(self): 
-    return str(self.__dict__)
-
-  def __repr__(self): 
-    return repr(self.__dict__)
-
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
-
-
diff --git a/contrib/fb303/py/fb303/__init__.py b/contrib/fb303/py/fb303/__init__.py
deleted file mode 100644
index 14c89e0..0000000
--- a/contrib/fb303/py/fb303/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__all__ = ['ttypes', 'constants', 'FacebookService']
diff --git a/contrib/fb303/py/fb303/constants.py b/contrib/fb303/py/fb303/constants.py
deleted file mode 100644
index 2f17ec3..0000000
--- a/contrib/fb303/py/fb303/constants.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Autogenerated by Thrift
-#
-# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
-#
-
-from thrift.Thrift import *
-from ttypes import *
-
diff --git a/contrib/fb303/py/fb303/ttypes.py b/contrib/fb303/py/fb303/ttypes.py
deleted file mode 100644
index 69b48ea..0000000
--- a/contrib/fb303/py/fb303/ttypes.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Autogenerated by Thrift
-#
-# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
-#
-
-from thrift.Thrift import *
-import thrift.reflection.limited.ttypes
-
-
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-try:
-  from thrift.protocol import fastbinary
-except:
-  fastbinary = None
-
-
-class fb_status:
-  DEAD = 0
-  STARTING = 1
-  ALIVE = 2
-  STOPPING = 3
-  STOPPED = 4
-  WARNING = 5
-
