/**
 * Autogenerated by Thrift Compiler (0.8.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.hadoop.hbase.thrift2.generated;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class THBaseService {

  public interface Iface {

    /**
     * Test for the existence of columns in the table, as specified in the TGet.
     * 
     * @return true if the specified TGet matches one or more keys, false if not
     * 
     * @param table the table to check on
     * 
     * @param get the TGet to check for
     */
    public boolean exists(ByteBuffer table, TGet get) throws TIOError, org.apache.thrift.TException;

    /**
     * Method for getting data from a row.
     * 
     * If the row cannot be found an empty Result is returned.
     * This can be checked by the empty field of the TResult
     * 
     * @return the result
     * 
     * @param table the table to get from
     * 
     * @param get the TGet to fetch
     */
    public TResult get(ByteBuffer table, TGet get) throws TIOError, org.apache.thrift.TException;

    /**
     * Method for getting multiple rows.
     * 
     * If a row cannot be found there will be a null
     * value in the result list for that TGet at the
     * same position.
     * 
     * So the Results are in the same order as the TGets.
     * 
     * @param table the table to get from
     * 
     * @param gets a list of TGets to fetch, the Result list
     * will have the Results at corresponding positions
     * or null if there was an error
     */
    public List<TResult> getMultiple(ByteBuffer table, List<TGet> gets) throws TIOError, org.apache.thrift.TException;

    /**
     * Commit a TPut to a table.
     * 
     * @param table the table to put data in
     * 
     * @param put the TPut to put
     */
    public void put(ByteBuffer table, TPut put) throws TIOError, org.apache.thrift.TException;

    /**
     * Atomically checks if a row/family/qualifier value matches the expected
     * value. If it does, it adds the TPut.
     * 
     * @return true if the new put was executed, false otherwise
     * 
     * @param table to check in and put to
     * 
     * @param row row to check
     * 
     * @param family column family to check
     * 
     * @param qualifier column qualifier to check
     * 
     * @param value the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     * 
     * @param put the TPut to put if the check succeeds
     */
    public boolean checkAndPut(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TPut put) throws TIOError, org.apache.thrift.TException;

    /**
     * Commit a List of Puts to the table.
     * 
     * @param table the table to put data in
     * 
     * @param puts a list of TPuts to commit
     */
    public void putMultiple(ByteBuffer table, List<TPut> puts) throws TIOError, org.apache.thrift.TException;

    /**
     * Deletes as specified by the TDelete.
     * 
     * Note: "delete" is a reserved keyword and cannot be used in Thrift
     * thus the inconsistent naming scheme from the other functions.
     * 
     * @param table the table to delete from
     * 
     * @param deleteSingle the TDelete to delete
     */
    public void deleteSingle(ByteBuffer table, TDelete deleteSingle) throws TIOError, org.apache.thrift.TException;

    /**
     * Bulk commit a List of TDeletes to the table.
     * 
     * This returns a list of TDeletes that were not
     * executed. So if everything succeeds you'll
     * receive an empty list.
     * 
     * @param table the table to delete from
     * 
     * @param deletes list of TDeletes to delete
     */
    public List<TDelete> deleteMultiple(ByteBuffer table, List<TDelete> deletes) throws TIOError, org.apache.thrift.TException;

    /**
     * Atomically checks if a row/family/qualifier value matches the expected
     * value. If it does, it adds the delete.
     * 
     * @return true if the new delete was executed, false otherwise
     * 
     * @param table to check in and delete from
     * 
     * @param row row to check
     * 
     * @param family column family to check
     * 
     * @param qualifier column qualifier to check
     * 
     * @param value the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     * 
     * @param deleteSingle the TDelete to execute if the check succeeds
     */
    public boolean checkAndDelete(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle) throws TIOError, org.apache.thrift.TException;

    public TResult increment(ByteBuffer table, TIncrement increment) throws TIOError, org.apache.thrift.TException;

    /**
     * Get a Scanner for the provided TScan object.
     * 
     * @return Scanner Id to be used with other scanner procedures
     * 
     * @param table the table to get the Scanner for
     * 
     * @param scan the scan object to get a Scanner for
     */
    public int openScanner(ByteBuffer table, TScan scan) throws TIOError, org.apache.thrift.TException;

    /**
     * Grabs multiple rows from a Scanner.
     * 
     * @return Between zero and numRows TResults
     * 
     * @param scannerId the Id of the Scanner to return rows from. This is an Id returned from the openScanner function.
     * 
     * @param numRows number of rows to return
     */
    public List<TResult> getScannerRows(int scannerId, int numRows) throws TIOError, TIllegalArgument, org.apache.thrift.TException;

    /**
     * Closes the scanner. Should be called if you need to close
     * the Scanner before all results are read.
     * 
     * Exhausted scanners are closed automatically.
     * 
     * @param scannerId the Id of the Scanner to close *
     */
    public void closeScanner(int scannerId) throws TIOError, TIllegalArgument, org.apache.thrift.TException;

  }

  public interface AsyncIface {

    public void exists(ByteBuffer table, TGet get, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.exists_call> resultHandler) throws org.apache.thrift.TException;

    public void get(ByteBuffer table, TGet get, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.get_call> resultHandler) throws org.apache.thrift.TException;

    public void getMultiple(ByteBuffer table, List<TGet> gets, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.getMultiple_call> resultHandler) throws org.apache.thrift.TException;

    public void put(ByteBuffer table, TPut put, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.put_call> resultHandler) throws org.apache.thrift.TException;

    public void checkAndPut(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TPut put, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.checkAndPut_call> resultHandler) throws org.apache.thrift.TException;

    public void putMultiple(ByteBuffer table, List<TPut> puts, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.putMultiple_call> resultHandler) throws org.apache.thrift.TException;

    public void deleteSingle(ByteBuffer table, TDelete deleteSingle, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.deleteSingle_call> resultHandler) throws org.apache.thrift.TException;

    public void deleteMultiple(ByteBuffer table, List<TDelete> deletes, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.deleteMultiple_call> resultHandler) throws org.apache.thrift.TException;

    public void checkAndDelete(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.checkAndDelete_call> resultHandler) throws org.apache.thrift.TException;

    public void increment(ByteBuffer table, TIncrement increment, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.increment_call> resultHandler) throws org.apache.thrift.TException;

    public void openScanner(ByteBuffer table, TScan scan, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.openScanner_call> resultHandler) throws org.apache.thrift.TException;

    public void getScannerRows(int scannerId, int numRows, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.getScannerRows_call> resultHandler) throws org.apache.thrift.TException;

    public void closeScanner(int scannerId, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.closeScanner_call> resultHandler) throws org.apache.thrift.TException;

  }

  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
      public Factory() {}
      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
        return new Client(prot);
      }
      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

    public Client(org.apache.thrift.protocol.TProtocol prot)
    {
      super(prot, prot);
    }

    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
      super(iprot, oprot);
    }

    public boolean exists(ByteBuffer table, TGet get) throws TIOError, org.apache.thrift.TException
    {
      send_exists(table, get);
      return recv_exists();
    }

    public void send_exists(ByteBuffer table, TGet get) throws org.apache.thrift.TException
    {
      exists_args args = new exists_args();
      args.setTable(table);
      args.setGet(get);
      sendBase("exists", args);
    }

    public boolean recv_exists() throws TIOError, org.apache.thrift.TException
    {
      exists_result result = new exists_result();
      receiveBase(result, "exists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "exists failed: unknown result");
    }

    public TResult get(ByteBuffer table, TGet get) throws TIOError, org.apache.thrift.TException
    {
      send_get(table, get);
      return recv_get();
    }

    public void send_get(ByteBuffer table, TGet get) throws org.apache.thrift.TException
    {
      get_args args = new get_args();
      args.setTable(table);
      args.setGet(get);
      sendBase("get", args);
    }

    public TResult recv_get() throws TIOError, org.apache.thrift.TException
    {
      get_result result = new get_result();
      receiveBase(result, "get");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get failed: unknown result");
    }

    public List<TResult> getMultiple(ByteBuffer table, List<TGet> gets) throws TIOError, org.apache.thrift.TException
    {
      send_getMultiple(table, gets);
      return recv_getMultiple();
    }

    public void send_getMultiple(ByteBuffer table, List<TGet> gets) throws org.apache.thrift.TException
    {
      getMultiple_args args = new getMultiple_args();
      args.setTable(table);
      args.setGets(gets);
      sendBase("getMultiple", args);
    }

    public List<TResult> recv_getMultiple() throws TIOError, org.apache.thrift.TException
    {
      getMultiple_result result = new getMultiple_result();
      receiveBase(result, "getMultiple");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getMultiple failed: unknown result");
    }

    public void put(ByteBuffer table, TPut put) throws TIOError, org.apache.thrift.TException
    {
      send_put(table, put);
      recv_put();
    }

    public void send_put(ByteBuffer table, TPut put) throws org.apache.thrift.TException
    {
      put_args args = new put_args();
      args.setTable(table);
      args.setPut(put);
      sendBase("put", args);
    }

    public void recv_put() throws TIOError, org.apache.thrift.TException
    {
      put_result result = new put_result();
      receiveBase(result, "put");
      if (result.io != null) {
        throw result.io;
      }
      return;
    }

    public boolean checkAndPut(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TPut put) throws TIOError, org.apache.thrift.TException
    {
      send_checkAndPut(table, row, family, qualifier, value, put);
      return recv_checkAndPut();
    }

    public void send_checkAndPut(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TPut put) throws org.apache.thrift.TException
    {
      checkAndPut_args args = new checkAndPut_args();
      args.setTable(table);
      args.setRow(row);
      args.setFamily(family);
      args.setQualifier(qualifier);
      args.setValue(value);
      args.setPut(put);
      sendBase("checkAndPut", args);
    }

    public boolean recv_checkAndPut() throws TIOError, org.apache.thrift.TException
    {
      checkAndPut_result result = new checkAndPut_result();
      receiveBase(result, "checkAndPut");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "checkAndPut failed: unknown result");
    }

    public void putMultiple(ByteBuffer table, List<TPut> puts) throws TIOError, org.apache.thrift.TException
    {
      send_putMultiple(table, puts);
      recv_putMultiple();
    }

    public void send_putMultiple(ByteBuffer table, List<TPut> puts) throws org.apache.thrift.TException
    {
      putMultiple_args args = new putMultiple_args();
      args.setTable(table);
      args.setPuts(puts);
      sendBase("putMultiple", args);
    }

    public void recv_putMultiple() throws TIOError, org.apache.thrift.TException
    {
      putMultiple_result result = new putMultiple_result();
      receiveBase(result, "putMultiple");
      if (result.io != null) {
        throw result.io;
      }
      return;
    }

    public void deleteSingle(ByteBuffer table, TDelete deleteSingle) throws TIOError, org.apache.thrift.TException
    {
      send_deleteSingle(table, deleteSingle);
      recv_deleteSingle();
    }

    public void send_deleteSingle(ByteBuffer table, TDelete deleteSingle) throws org.apache.thrift.TException
    {
      deleteSingle_args args = new deleteSingle_args();
      args.setTable(table);
      args.setDeleteSingle(deleteSingle);
      sendBase("deleteSingle", args);
    }

    public void recv_deleteSingle() throws TIOError, org.apache.thrift.TException
    {
      deleteSingle_result result = new deleteSingle_result();
      receiveBase(result, "deleteSingle");
      if (result.io != null) {
        throw result.io;
      }
      return;
    }

    public List<TDelete> deleteMultiple(ByteBuffer table, List<TDelete> deletes) throws TIOError, org.apache.thrift.TException
    {
      send_deleteMultiple(table, deletes);
      return recv_deleteMultiple();
    }

    public void send_deleteMultiple(ByteBuffer table, List<TDelete> deletes) throws org.apache.thrift.TException
    {
      deleteMultiple_args args = new deleteMultiple_args();
      args.setTable(table);
      args.setDeletes(deletes);
      sendBase("deleteMultiple", args);
    }

    public List<TDelete> recv_deleteMultiple() throws TIOError, org.apache.thrift.TException
    {
      deleteMultiple_result result = new deleteMultiple_result();
      receiveBase(result, "deleteMultiple");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteMultiple failed: unknown result");
    }

    public boolean checkAndDelete(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle) throws TIOError, org.apache.thrift.TException
    {
      send_checkAndDelete(table, row, family, qualifier, value, deleteSingle);
      return recv_checkAndDelete();
    }

    public void send_checkAndDelete(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle) throws org.apache.thrift.TException
    {
      checkAndDelete_args args = new checkAndDelete_args();
      args.setTable(table);
      args.setRow(row);
      args.setFamily(family);
      args.setQualifier(qualifier);
      args.setValue(value);
      args.setDeleteSingle(deleteSingle);
      sendBase("checkAndDelete", args);
    }

    public boolean recv_checkAndDelete() throws TIOError, org.apache.thrift.TException
    {
      checkAndDelete_result result = new checkAndDelete_result();
      receiveBase(result, "checkAndDelete");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "checkAndDelete failed: unknown result");
    }

    public TResult increment(ByteBuffer table, TIncrement increment) throws TIOError, org.apache.thrift.TException
    {
      send_increment(table, increment);
      return recv_increment();
    }

    public void send_increment(ByteBuffer table, TIncrement increment) throws org.apache.thrift.TException
    {
      increment_args args = new increment_args();
      args.setTable(table);
      args.setIncrement(increment);
      sendBase("increment", args);
    }

    public TResult recv_increment() throws TIOError, org.apache.thrift.TException
    {
      increment_result result = new increment_result();
      receiveBase(result, "increment");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "increment failed: unknown result");
    }

    public int openScanner(ByteBuffer table, TScan scan) throws TIOError, org.apache.thrift.TException
    {
      send_openScanner(table, scan);
      return recv_openScanner();
    }

    public void send_openScanner(ByteBuffer table, TScan scan) throws org.apache.thrift.TException
    {
      openScanner_args args = new openScanner_args();
      args.setTable(table);
      args.setScan(scan);
      sendBase("openScanner", args);
    }

    public int recv_openScanner() throws TIOError, org.apache.thrift.TException
    {
      openScanner_result result = new openScanner_result();
      receiveBase(result, "openScanner");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "openScanner failed: unknown result");
    }

    public List<TResult> getScannerRows(int scannerId, int numRows) throws TIOError, TIllegalArgument, org.apache.thrift.TException
    {
      send_getScannerRows(scannerId, numRows);
      return recv_getScannerRows();
    }

    public void send_getScannerRows(int scannerId, int numRows) throws org.apache.thrift.TException
    {
      getScannerRows_args args = new getScannerRows_args();
      args.setScannerId(scannerId);
      args.setNumRows(numRows);
      sendBase("getScannerRows", args);
    }

    public List<TResult> recv_getScannerRows() throws TIOError, TIllegalArgument, org.apache.thrift.TException
    {
      getScannerRows_result result = new getScannerRows_result();
      receiveBase(result, "getScannerRows");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.io != null) {
        throw result.io;
      }
      if (result.ia != null) {
        throw result.ia;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getScannerRows failed: unknown result");
    }

    public void closeScanner(int scannerId) throws TIOError, TIllegalArgument, org.apache.thrift.TException
    {
      send_closeScanner(scannerId);
      recv_closeScanner();
    }

    public void send_closeScanner(int scannerId) throws org.apache.thrift.TException
    {
      closeScanner_args args = new closeScanner_args();
      args.setScannerId(scannerId);
      sendBase("closeScanner", args);
    }

    public void recv_closeScanner() throws TIOError, TIllegalArgument, org.apache.thrift.TException
    {
      closeScanner_result result = new closeScanner_result();
      receiveBase(result, "closeScanner");
      if (result.io != null) {
        throw result.io;
      }
      if (result.ia != null) {
        throw result.ia;
      }
      return;
    }

  }
  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
      private org.apache.thrift.async.TAsyncClientManager clientManager;
      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
        this.clientManager = clientManager;
        this.protocolFactory = protocolFactory;
      }
      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
        return new AsyncClient(protocolFactory, clientManager, transport);
      }
    }

    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
      super(protocolFactory, clientManager, transport);
    }

    public void exists(ByteBuffer table, TGet get, org.apache.thrift.async.AsyncMethodCallback<exists_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      exists_call method_call = new exists_call(table, get, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class exists_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private TGet get;
      public exists_call(ByteBuffer table, TGet get, org.apache.thrift.async.AsyncMethodCallback<exists_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.get = get;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("exists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        exists_args args = new exists_args();
        args.setTable(table);
        args.setGet(get);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_exists();
      }
    }

    public void get(ByteBuffer table, TGet get, org.apache.thrift.async.AsyncMethodCallback<get_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_call method_call = new get_call(table, get, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private TGet get;
      public get_call(ByteBuffer table, TGet get, org.apache.thrift.async.AsyncMethodCallback<get_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.get = get;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_args args = new get_args();
        args.setTable(table);
        args.setGet(get);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public TResult getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_get();
      }
    }

    public void getMultiple(ByteBuffer table, List<TGet> gets, org.apache.thrift.async.AsyncMethodCallback<getMultiple_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getMultiple_call method_call = new getMultiple_call(table, gets, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getMultiple_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private List<TGet> gets;
      public getMultiple_call(ByteBuffer table, List<TGet> gets, org.apache.thrift.async.AsyncMethodCallback<getMultiple_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.gets = gets;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getMultiple", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getMultiple_args args = new getMultiple_args();
        args.setTable(table);
        args.setGets(gets);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<TResult> getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getMultiple();
      }
    }

    public void put(ByteBuffer table, TPut put, org.apache.thrift.async.AsyncMethodCallback<put_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      put_call method_call = new put_call(table, put, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class put_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private TPut put;
      public put_call(ByteBuffer table, TPut put, org.apache.thrift.async.AsyncMethodCallback<put_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.put = put;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("put", org.apache.thrift.protocol.TMessageType.CALL, 0));
        put_args args = new put_args();
        args.setTable(table);
        args.setPut(put);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_put();
      }
    }

    public void checkAndPut(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TPut put, org.apache.thrift.async.AsyncMethodCallback<checkAndPut_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      checkAndPut_call method_call = new checkAndPut_call(table, row, family, qualifier, value, put, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class checkAndPut_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private ByteBuffer row;
      private ByteBuffer family;
      private ByteBuffer qualifier;
      private ByteBuffer value;
      private TPut put;
      public checkAndPut_call(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TPut put, org.apache.thrift.async.AsyncMethodCallback<checkAndPut_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.row = row;
        this.family = family;
        this.qualifier = qualifier;
        this.value = value;
        this.put = put;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("checkAndPut", org.apache.thrift.protocol.TMessageType.CALL, 0));
        checkAndPut_args args = new checkAndPut_args();
        args.setTable(table);
        args.setRow(row);
        args.setFamily(family);
        args.setQualifier(qualifier);
        args.setValue(value);
        args.setPut(put);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_checkAndPut();
      }
    }

    public void putMultiple(ByteBuffer table, List<TPut> puts, org.apache.thrift.async.AsyncMethodCallback<putMultiple_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      putMultiple_call method_call = new putMultiple_call(table, puts, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class putMultiple_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private List<TPut> puts;
      public putMultiple_call(ByteBuffer table, List<TPut> puts, org.apache.thrift.async.AsyncMethodCallback<putMultiple_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.puts = puts;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("putMultiple", org.apache.thrift.protocol.TMessageType.CALL, 0));
        putMultiple_args args = new putMultiple_args();
        args.setTable(table);
        args.setPuts(puts);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_putMultiple();
      }
    }

    public void deleteSingle(ByteBuffer table, TDelete deleteSingle, org.apache.thrift.async.AsyncMethodCallback<deleteSingle_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteSingle_call method_call = new deleteSingle_call(table, deleteSingle, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteSingle_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private TDelete deleteSingle;
      public deleteSingle_call(ByteBuffer table, TDelete deleteSingle, org.apache.thrift.async.AsyncMethodCallback<deleteSingle_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.deleteSingle = deleteSingle;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteSingle", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteSingle_args args = new deleteSingle_args();
        args.setTable(table);
        args.setDeleteSingle(deleteSingle);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_deleteSingle();
      }
    }

    public void deleteMultiple(ByteBuffer table, List<TDelete> deletes, org.apache.thrift.async.AsyncMethodCallback<deleteMultiple_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteMultiple_call method_call = new deleteMultiple_call(table, deletes, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteMultiple_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private List<TDelete> deletes;
      public deleteMultiple_call(ByteBuffer table, List<TDelete> deletes, org.apache.thrift.async.AsyncMethodCallback<deleteMultiple_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.deletes = deletes;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteMultiple", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteMultiple_args args = new deleteMultiple_args();
        args.setTable(table);
        args.setDeletes(deletes);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<TDelete> getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteMultiple();
      }
    }

    public void checkAndDelete(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle, org.apache.thrift.async.AsyncMethodCallback<checkAndDelete_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      checkAndDelete_call method_call = new checkAndDelete_call(table, row, family, qualifier, value, deleteSingle, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class checkAndDelete_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private ByteBuffer row;
      private ByteBuffer family;
      private ByteBuffer qualifier;
      private ByteBuffer value;
      private TDelete deleteSingle;
      public checkAndDelete_call(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, ByteBuffer value, TDelete deleteSingle, org.apache.thrift.async.AsyncMethodCallback<checkAndDelete_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.row = row;
        this.family = family;
        this.qualifier = qualifier;
        this.value = value;
        this.deleteSingle = deleteSingle;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("checkAndDelete", org.apache.thrift.protocol.TMessageType.CALL, 0));
        checkAndDelete_args args = new checkAndDelete_args();
        args.setTable(table);
        args.setRow(row);
        args.setFamily(family);
        args.setQualifier(qualifier);
        args.setValue(value);
        args.setDeleteSingle(deleteSingle);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public boolean getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_checkAndDelete();
      }
    }

    public void increment(ByteBuffer table, TIncrement increment, org.apache.thrift.async.AsyncMethodCallback<increment_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      increment_call method_call = new increment_call(table, increment, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class increment_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private TIncrement increment;
      public increment_call(ByteBuffer table, TIncrement increment, org.apache.thrift.async.AsyncMethodCallback<increment_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.increment = increment;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("increment", org.apache.thrift.protocol.TMessageType.CALL, 0));
        increment_args args = new increment_args();
        args.setTable(table);
        args.setIncrement(increment);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public TResult getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_increment();
      }
    }

    public void openScanner(ByteBuffer table, TScan scan, org.apache.thrift.async.AsyncMethodCallback<openScanner_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      openScanner_call method_call = new openScanner_call(table, scan, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class openScanner_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer table;
      private TScan scan;
      public openScanner_call(ByteBuffer table, TScan scan, org.apache.thrift.async.AsyncMethodCallback<openScanner_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.table = table;
        this.scan = scan;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("openScanner", org.apache.thrift.protocol.TMessageType.CALL, 0));
        openScanner_args args = new openScanner_args();
        args.setTable(table);
        args.setScan(scan);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public int getResult() throws TIOError, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_openScanner();
      }
    }

    public void getScannerRows(int scannerId, int numRows, org.apache.thrift.async.AsyncMethodCallback<getScannerRows_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getScannerRows_call method_call = new getScannerRows_call(scannerId, numRows, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getScannerRows_call extends org.apache.thrift.async.TAsyncMethodCall {
      private int scannerId;
      private int numRows;
      public getScannerRows_call(int scannerId, int numRows, org.apache.thrift.async.AsyncMethodCallback<getScannerRows_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.scannerId = scannerId;
        this.numRows = numRows;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getScannerRows", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getScannerRows_args args = new getScannerRows_args();
        args.setScannerId(scannerId);
        args.setNumRows(numRows);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<TResult> getResult() throws TIOError, TIllegalArgument, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getScannerRows();
      }
    }

    public void closeScanner(int scannerId, org.apache.thrift.async.AsyncMethodCallback<closeScanner_call> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      closeScanner_call method_call = new closeScanner_call(scannerId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class closeScanner_call extends org.apache.thrift.async.TAsyncMethodCall {
      private int scannerId;
      public closeScanner_call(int scannerId, org.apache.thrift.async.AsyncMethodCallback<closeScanner_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.scannerId = scannerId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("closeScanner", org.apache.thrift.protocol.TMessageType.CALL, 0));
        closeScanner_args args = new closeScanner_args();
        args.setScannerId(scannerId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws TIOError, TIllegalArgument, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        (new Client(prot)).recv_closeScanner();
      }
    }

  }

  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
    private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
    public Processor(I iface) {
      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
    }

    protected Processor(I iface, Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      processMap.put("exists", new exists());
      processMap.put("get", new get());
      processMap.put("getMultiple", new getMultiple());
      processMap.put("put", new put());
      processMap.put("checkAndPut", new checkAndPut());
      processMap.put("putMultiple", new putMultiple());
      processMap.put("deleteSingle", new deleteSingle());
      processMap.put("deleteMultiple", new deleteMultiple());
      processMap.put("checkAndDelete", new checkAndDelete());
      processMap.put("increment", new increment());
      processMap.put("openScanner", new openScanner());
      processMap.put("getScannerRows", new getScannerRows());
      processMap.put("closeScanner", new closeScanner());
      return processMap;
    }

    private static class exists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, exists_args> {
      public exists() {
        super("exists");
      }

      protected exists_args getEmptyArgsInstance() {
        return new exists_args();
      }

      protected exists_result getResult(I iface, exists_args args) throws org.apache.thrift.TException {
        exists_result result = new exists_result();
        try {
          result.success = iface.exists(args.table, args.get);
          result.setSuccessIsSet(true);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class get<I extends Iface> extends org.apache.thrift.ProcessFunction<I, get_args> {
      public get() {
        super("get");
      }

      protected get_args getEmptyArgsInstance() {
        return new get_args();
      }

      protected get_result getResult(I iface, get_args args) throws org.apache.thrift.TException {
        get_result result = new get_result();
        try {
          result.success = iface.get(args.table, args.get);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class getMultiple<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getMultiple_args> {
      public getMultiple() {
        super("getMultiple");
      }

      protected getMultiple_args getEmptyArgsInstance() {
        return new getMultiple_args();
      }

      protected getMultiple_result getResult(I iface, getMultiple_args args) throws org.apache.thrift.TException {
        getMultiple_result result = new getMultiple_result();
        try {
          result.success = iface.getMultiple(args.table, args.gets);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class put<I extends Iface> extends org.apache.thrift.ProcessFunction<I, put_args> {
      public put() {
        super("put");
      }

      protected put_args getEmptyArgsInstance() {
        return new put_args();
      }

      protected put_result getResult(I iface, put_args args) throws org.apache.thrift.TException {
        put_result result = new put_result();
        try {
          iface.put(args.table, args.put);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class checkAndPut<I extends Iface> extends org.apache.thrift.ProcessFunction<I, checkAndPut_args> {
      public checkAndPut() {
        super("checkAndPut");
      }

      protected checkAndPut_args getEmptyArgsInstance() {
        return new checkAndPut_args();
      }

      protected checkAndPut_result getResult(I iface, checkAndPut_args args) throws org.apache.thrift.TException {
        checkAndPut_result result = new checkAndPut_result();
        try {
          result.success = iface.checkAndPut(args.table, args.row, args.family, args.qualifier, args.value, args.put);
          result.setSuccessIsSet(true);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class putMultiple<I extends Iface> extends org.apache.thrift.ProcessFunction<I, putMultiple_args> {
      public putMultiple() {
        super("putMultiple");
      }

      protected putMultiple_args getEmptyArgsInstance() {
        return new putMultiple_args();
      }

      protected putMultiple_result getResult(I iface, putMultiple_args args) throws org.apache.thrift.TException {
        putMultiple_result result = new putMultiple_result();
        try {
          iface.putMultiple(args.table, args.puts);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class deleteSingle<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteSingle_args> {
      public deleteSingle() {
        super("deleteSingle");
      }

      protected deleteSingle_args getEmptyArgsInstance() {
        return new deleteSingle_args();
      }

      protected deleteSingle_result getResult(I iface, deleteSingle_args args) throws org.apache.thrift.TException {
        deleteSingle_result result = new deleteSingle_result();
        try {
          iface.deleteSingle(args.table, args.deleteSingle);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class deleteMultiple<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteMultiple_args> {
      public deleteMultiple() {
        super("deleteMultiple");
      }

      protected deleteMultiple_args getEmptyArgsInstance() {
        return new deleteMultiple_args();
      }

      protected deleteMultiple_result getResult(I iface, deleteMultiple_args args) throws org.apache.thrift.TException {
        deleteMultiple_result result = new deleteMultiple_result();
        try {
          result.success = iface.deleteMultiple(args.table, args.deletes);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class checkAndDelete<I extends Iface> extends org.apache.thrift.ProcessFunction<I, checkAndDelete_args> {
      public checkAndDelete() {
        super("checkAndDelete");
      }

      protected checkAndDelete_args getEmptyArgsInstance() {
        return new checkAndDelete_args();
      }

      protected checkAndDelete_result getResult(I iface, checkAndDelete_args args) throws org.apache.thrift.TException {
        checkAndDelete_result result = new checkAndDelete_result();
        try {
          result.success = iface.checkAndDelete(args.table, args.row, args.family, args.qualifier, args.value, args.deleteSingle);
          result.setSuccessIsSet(true);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class increment<I extends Iface> extends org.apache.thrift.ProcessFunction<I, increment_args> {
      public increment() {
        super("increment");
      }

      protected increment_args getEmptyArgsInstance() {
        return new increment_args();
      }

      protected increment_result getResult(I iface, increment_args args) throws org.apache.thrift.TException {
        increment_result result = new increment_result();
        try {
          result.success = iface.increment(args.table, args.increment);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class openScanner<I extends Iface> extends org.apache.thrift.ProcessFunction<I, openScanner_args> {
      public openScanner() {
        super("openScanner");
      }

      protected openScanner_args getEmptyArgsInstance() {
        return new openScanner_args();
      }

      protected openScanner_result getResult(I iface, openScanner_args args) throws org.apache.thrift.TException {
        openScanner_result result = new openScanner_result();
        try {
          result.success = iface.openScanner(args.table, args.scan);
          result.setSuccessIsSet(true);
        } catch (TIOError io) {
          result.io = io;
        }
        return result;
      }
    }

    private static class getScannerRows<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getScannerRows_args> {
      public getScannerRows() {
        super("getScannerRows");
      }

      protected getScannerRows_args getEmptyArgsInstance() {
        return new getScannerRows_args();
      }

      protected getScannerRows_result getResult(I iface, getScannerRows_args args) throws org.apache.thrift.TException {
        getScannerRows_result result = new getScannerRows_result();
        try {
          result.success = iface.getScannerRows(args.scannerId, args.numRows);
        } catch (TIOError io) {
          result.io = io;
        } catch (TIllegalArgument ia) {
          result.ia = ia;
        }
        return result;
      }
    }

    private static class closeScanner<I extends Iface> extends org.apache.thrift.ProcessFunction<I, closeScanner_args> {
      public closeScanner() {
        super("closeScanner");
      }

      protected closeScanner_args getEmptyArgsInstance() {
        return new closeScanner_args();
      }

      protected closeScanner_result getResult(I iface, closeScanner_args args) throws org.apache.thrift.TException {
        closeScanner_result result = new closeScanner_result();
        try {
          iface.closeScanner(args.scannerId);
        } catch (TIOError io) {
          result.io = io;
        } catch (TIllegalArgument ia) {
          result.ia = ia;
        }
        return result;
      }
    }

  }

  public static class exists_args implements org.apache.thrift.TBase<exists_args, exists_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("exists_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GET_FIELD_DESC = new org.apache.thrift.protocol.TField("get", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new exists_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new exists_argsTupleSchemeFactory());
    }

    /**
     * the table to check on
     */
    public ByteBuffer table; // required
    /**
     * the TGet to check for
     */
    public TGet get; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to check on
       */
      TABLE((short)1, "table"),
      /**
       * the TGet to check for
       */
      GET((short)2, "get");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // GET
            return GET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.GET, new org.apache.thrift.meta_data.FieldMetaData("get", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TGet.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(exists_args.class, metaDataMap);
    }

    public exists_args() {
    }

    public exists_args(
      ByteBuffer table,
      TGet get)
    {
      this();
      this.table = table;
      this.get = get;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public exists_args(exists_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetGet()) {
        this.get = new TGet(other.get);
      }
    }

    public exists_args deepCopy() {
      return new exists_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.get = null;
    }

    /**
     * the table to check on
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to check on
     */
    public exists_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public exists_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * the TGet to check for
     */
    public TGet getGet() {
      return this.get;
    }

    /**
     * the TGet to check for
     */
    public exists_args setGet(TGet get) {
      this.get = get;
      return this;
    }

    public void unsetGet() {
      this.get = null;
    }

    /** Returns true if field get is set (has been assigned a value) and false otherwise */
    public boolean isSetGet() {
      return this.get != null;
    }

    public void setGetIsSet(boolean value) {
      if (!value) {
        this.get = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case GET:
        if (value == null) {
          unsetGet();
        } else {
          setGet((TGet)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case GET:
        return getGet();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case GET:
        return isSetGet();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof exists_args)
        return this.equals((exists_args)that);
      return false;
    }

    public boolean equals(exists_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_get = true && this.isSetGet();
      boolean that_present_get = true && that.isSetGet();
      if (this_present_get || that_present_get) {
        if (!(this_present_get && that_present_get))
          return false;
        if (!this.get.equals(that.get))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(exists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      exists_args typedOther = (exists_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetGet()).compareTo(typedOther.isSetGet());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGet()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.get, typedOther.get);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("exists_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("get:");
      if (this.get == null) {
        sb.append("null");
      } else {
        sb.append(this.get);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (get == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'get' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class exists_argsStandardSchemeFactory implements SchemeFactory {
      public exists_argsStandardScheme getScheme() {
        return new exists_argsStandardScheme();
      }
    }

    private static class exists_argsStandardScheme extends StandardScheme<exists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, exists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GET
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.get = new TGet();
                struct.get.read(iprot);
                struct.setGetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, exists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.get != null) {
          oprot.writeFieldBegin(GET_FIELD_DESC);
          struct.get.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class exists_argsTupleSchemeFactory implements SchemeFactory {
      public exists_argsTupleScheme getScheme() {
        return new exists_argsTupleScheme();
      }
    }

    private static class exists_argsTupleScheme extends TupleScheme<exists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, exists_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        struct.get.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, exists_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.get = new TGet();
        struct.get.read(iprot);
        struct.setGetIsSet(true);
      }
    }

  }

  public static class exists_result implements org.apache.thrift.TBase<exists_result, exists_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("exists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new exists_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new exists_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private BitSet __isset_bit_vector = new BitSet(1);
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(exists_result.class, metaDataMap);
    }

    public exists_result() {
    }

    public exists_result(
      boolean success,
      TIOError io)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public exists_result(exists_result other) {
      __isset_bit_vector.clear();
      __isset_bit_vector.or(other.__isset_bit_vector);
      this.success = other.success;
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public exists_result deepCopy() {
      return new exists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.io = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public exists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
    }

    public TIOError getIo() {
      return this.io;
    }

    public exists_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof exists_result)
        return this.equals((exists_result)that);
      return false;
    }

    public boolean equals(exists_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(exists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      exists_result typedOther = (exists_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("exists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class exists_resultStandardSchemeFactory implements SchemeFactory {
      public exists_resultStandardScheme getScheme() {
        return new exists_resultStandardScheme();
      }
    }

    private static class exists_resultStandardScheme extends StandardScheme<exists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, exists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, exists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
        oprot.writeBool(struct.success);
        oprot.writeFieldEnd();
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class exists_resultTupleSchemeFactory implements SchemeFactory {
      public exists_resultTupleScheme getScheme() {
        return new exists_resultTupleScheme();
      }
    }

    private static class exists_resultTupleScheme extends TupleScheme<exists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, exists_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, exists_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class get_args implements org.apache.thrift.TBase<get_args, get_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GET_FIELD_DESC = new org.apache.thrift.protocol.TField("get", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new get_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new get_argsTupleSchemeFactory());
    }

    /**
     * the table to get from
     */
    public ByteBuffer table; // required
    /**
     * the TGet to fetch
     */
    public TGet get; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to get from
       */
      TABLE((short)1, "table"),
      /**
       * the TGet to fetch
       */
      GET((short)2, "get");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // GET
            return GET;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.GET, new org.apache.thrift.meta_data.FieldMetaData("get", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TGet.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_args.class, metaDataMap);
    }

    public get_args() {
    }

    public get_args(
      ByteBuffer table,
      TGet get)
    {
      this();
      this.table = table;
      this.get = get;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_args(get_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetGet()) {
        this.get = new TGet(other.get);
      }
    }

    public get_args deepCopy() {
      return new get_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.get = null;
    }

    /**
     * the table to get from
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to get from
     */
    public get_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public get_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * the TGet to fetch
     */
    public TGet getGet() {
      return this.get;
    }

    /**
     * the TGet to fetch
     */
    public get_args setGet(TGet get) {
      this.get = get;
      return this;
    }

    public void unsetGet() {
      this.get = null;
    }

    /** Returns true if field get is set (has been assigned a value) and false otherwise */
    public boolean isSetGet() {
      return this.get != null;
    }

    public void setGetIsSet(boolean value) {
      if (!value) {
        this.get = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case GET:
        if (value == null) {
          unsetGet();
        } else {
          setGet((TGet)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case GET:
        return getGet();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case GET:
        return isSetGet();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof get_args)
        return this.equals((get_args)that);
      return false;
    }

    public boolean equals(get_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_get = true && this.isSetGet();
      boolean that_present_get = true && that.isSetGet();
      if (this_present_get || that_present_get) {
        if (!(this_present_get && that_present_get))
          return false;
        if (!this.get.equals(that.get))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(get_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      get_args typedOther = (get_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetGet()).compareTo(typedOther.isSetGet());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGet()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.get, typedOther.get);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("get_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("get:");
      if (this.get == null) {
        sb.append("null");
      } else {
        sb.append(this.get);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (get == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'get' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class get_argsStandardSchemeFactory implements SchemeFactory {
      public get_argsStandardScheme getScheme() {
        return new get_argsStandardScheme();
      }
    }

    private static class get_argsStandardScheme extends StandardScheme<get_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GET
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.get = new TGet();
                struct.get.read(iprot);
                struct.setGetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, get_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.get != null) {
          oprot.writeFieldBegin(GET_FIELD_DESC);
          struct.get.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_argsTupleSchemeFactory implements SchemeFactory {
      public get_argsTupleScheme getScheme() {
        return new get_argsTupleScheme();
      }
    }

    private static class get_argsTupleScheme extends TupleScheme<get_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        struct.get.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.get = new TGet();
        struct.get.read(iprot);
        struct.setGetIsSet(true);
      }
    }

  }

  public static class get_result implements org.apache.thrift.TBase<get_result, get_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new get_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new get_resultTupleSchemeFactory());
    }

    public TResult success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TResult.class)));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_result.class, metaDataMap);
    }

    public get_result() {
    }

    public get_result(
      TResult success,
      TIOError io)
    {
      this();
      this.success = success;
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_result(get_result other) {
      if (other.isSetSuccess()) {
        this.success = new TResult(other.success);
      }
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public get_result deepCopy() {
      return new get_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.io = null;
    }

    public TResult getSuccess() {
      return this.success;
    }

    public get_result setSuccess(TResult success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public TIOError getIo() {
      return this.io;
    }

    public get_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((TResult)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof get_result)
        return this.equals((get_result)that);
      return false;
    }

    public boolean equals(get_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(get_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      get_result typedOther = (get_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("get_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class get_resultStandardSchemeFactory implements SchemeFactory {
      public get_resultStandardScheme getScheme() {
        return new get_resultStandardScheme();
      }
    }

    private static class get_resultStandardScheme extends StandardScheme<get_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new TResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, get_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_resultTupleSchemeFactory implements SchemeFactory {
      public get_resultTupleScheme getScheme() {
        return new get_resultTupleScheme();
      }
    }

    private static class get_resultTupleScheme extends TupleScheme<get_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new TResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class getMultiple_args implements org.apache.thrift.TBase<getMultiple_args, getMultiple_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getMultiple_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GETS_FIELD_DESC = new org.apache.thrift.protocol.TField("gets", org.apache.thrift.protocol.TType.LIST, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getMultiple_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getMultiple_argsTupleSchemeFactory());
    }

    /**
     * the table to get from
     */
    public ByteBuffer table; // required
    /**
     * a list of TGets to fetch, the Result list
     * will have the Results at corresponding positions
     * or null if there was an error
     */
    public List<TGet> gets; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to get from
       */
      TABLE((short)1, "table"),
      /**
       * a list of TGets to fetch, the Result list
       * will have the Results at corresponding positions
       * or null if there was an error
       */
      GETS((short)2, "gets");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // GETS
            return GETS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.GETS, new org.apache.thrift.meta_data.FieldMetaData("gets", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TGet.class))));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getMultiple_args.class, metaDataMap);
    }

    public getMultiple_args() {
    }

    public getMultiple_args(
      ByteBuffer table,
      List<TGet> gets)
    {
      this();
      this.table = table;
      this.gets = gets;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getMultiple_args(getMultiple_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetGets()) {
        List<TGet> __this__gets = new ArrayList<TGet>();
        for (TGet other_element : other.gets) {
          __this__gets.add(new TGet(other_element));
        }
        this.gets = __this__gets;
      }
    }

    public getMultiple_args deepCopy() {
      return new getMultiple_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.gets = null;
    }

    /**
     * the table to get from
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to get from
     */
    public getMultiple_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public getMultiple_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    public int getGetsSize() {
      return (this.gets == null) ? 0 : this.gets.size();
    }

    public java.util.Iterator<TGet> getGetsIterator() {
      return (this.gets == null) ? null : this.gets.iterator();
    }

    public void addToGets(TGet elem) {
      if (this.gets == null) {
        this.gets = new ArrayList<TGet>();
      }
      this.gets.add(elem);
    }

    /**
     * a list of TGets to fetch, the Result list
     * will have the Results at corresponding positions
     * or null if there was an error
     */
    public List<TGet> getGets() {
      return this.gets;
    }

    /**
     * a list of TGets to fetch, the Result list
     * will have the Results at corresponding positions
     * or null if there was an error
     */
    public getMultiple_args setGets(List<TGet> gets) {
      this.gets = gets;
      return this;
    }

    public void unsetGets() {
      this.gets = null;
    }

    /** Returns true if field gets is set (has been assigned a value) and false otherwise */
    public boolean isSetGets() {
      return this.gets != null;
    }

    public void setGetsIsSet(boolean value) {
      if (!value) {
        this.gets = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case GETS:
        if (value == null) {
          unsetGets();
        } else {
          setGets((List<TGet>)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case GETS:
        return getGets();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case GETS:
        return isSetGets();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getMultiple_args)
        return this.equals((getMultiple_args)that);
      return false;
    }

    public boolean equals(getMultiple_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_gets = true && this.isSetGets();
      boolean that_present_gets = true && that.isSetGets();
      if (this_present_gets || that_present_gets) {
        if (!(this_present_gets && that_present_gets))
          return false;
        if (!this.gets.equals(that.gets))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(getMultiple_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      getMultiple_args typedOther = (getMultiple_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetGets()).compareTo(typedOther.isSetGets());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGets()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gets, typedOther.gets);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getMultiple_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("gets:");
      if (this.gets == null) {
        sb.append("null");
      } else {
        sb.append(this.gets);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (gets == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'gets' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getMultiple_argsStandardSchemeFactory implements SchemeFactory {
      public getMultiple_argsStandardScheme getScheme() {
        return new getMultiple_argsStandardScheme();
      }
    }

    private static class getMultiple_argsStandardScheme extends StandardScheme<getMultiple_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getMultiple_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GETS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list48 = iprot.readListBegin();
                  struct.gets = new ArrayList<TGet>(_list48.size);
                  for (int _i49 = 0; _i49 < _list48.size; ++_i49)
                  {
                    TGet _elem50; // optional
                    _elem50 = new TGet();
                    _elem50.read(iprot);
                    struct.gets.add(_elem50);
                  }
                  iprot.readListEnd();
                }
                struct.setGetsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getMultiple_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.gets != null) {
          oprot.writeFieldBegin(GETS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.gets.size()));
            for (TGet _iter51 : struct.gets)
            {
              _iter51.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getMultiple_argsTupleSchemeFactory implements SchemeFactory {
      public getMultiple_argsTupleScheme getScheme() {
        return new getMultiple_argsTupleScheme();
      }
    }

    private static class getMultiple_argsTupleScheme extends TupleScheme<getMultiple_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getMultiple_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        {
          oprot.writeI32(struct.gets.size());
          for (TGet _iter52 : struct.gets)
          {
            _iter52.write(oprot);
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getMultiple_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        {
          org.apache.thrift.protocol.TList _list53 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.gets = new ArrayList<TGet>(_list53.size);
          for (int _i54 = 0; _i54 < _list53.size; ++_i54)
          {
            TGet _elem55; // optional
            _elem55 = new TGet();
            _elem55.read(iprot);
            struct.gets.add(_elem55);
          }
        }
        struct.setGetsIsSet(true);
      }
    }

  }

  public static class getMultiple_result implements org.apache.thrift.TBase<getMultiple_result, getMultiple_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getMultiple_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getMultiple_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getMultiple_resultTupleSchemeFactory());
    }

    public List<TResult> success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TResult.class))));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getMultiple_result.class, metaDataMap);
    }

    public getMultiple_result() {
    }

    public getMultiple_result(
      List<TResult> success,
      TIOError io)
    {
      this();
      this.success = success;
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getMultiple_result(getMultiple_result other) {
      if (other.isSetSuccess()) {
        List<TResult> __this__success = new ArrayList<TResult>();
        for (TResult other_element : other.success) {
          __this__success.add(new TResult(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public getMultiple_result deepCopy() {
      return new getMultiple_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.io = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<TResult> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(TResult elem) {
      if (this.success == null) {
        this.success = new ArrayList<TResult>();
      }
      this.success.add(elem);
    }

    public List<TResult> getSuccess() {
      return this.success;
    }

    public getMultiple_result setSuccess(List<TResult> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public TIOError getIo() {
      return this.io;
    }

    public getMultiple_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<TResult>)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getMultiple_result)
        return this.equals((getMultiple_result)that);
      return false;
    }

    public boolean equals(getMultiple_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(getMultiple_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      getMultiple_result typedOther = (getMultiple_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getMultiple_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getMultiple_resultStandardSchemeFactory implements SchemeFactory {
      public getMultiple_resultStandardScheme getScheme() {
        return new getMultiple_resultStandardScheme();
      }
    }

    private static class getMultiple_resultStandardScheme extends StandardScheme<getMultiple_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getMultiple_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list56 = iprot.readListBegin();
                  struct.success = new ArrayList<TResult>(_list56.size);
                  for (int _i57 = 0; _i57 < _list56.size; ++_i57)
                  {
                    TResult _elem58; // optional
                    _elem58 = new TResult();
                    _elem58.read(iprot);
                    struct.success.add(_elem58);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getMultiple_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (TResult _iter59 : struct.success)
            {
              _iter59.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getMultiple_resultTupleSchemeFactory implements SchemeFactory {
      public getMultiple_resultTupleScheme getScheme() {
        return new getMultiple_resultTupleScheme();
      }
    }

    private static class getMultiple_resultTupleScheme extends TupleScheme<getMultiple_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getMultiple_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (TResult _iter60 : struct.success)
            {
              _iter60.write(oprot);
            }
          }
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getMultiple_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list61 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<TResult>(_list61.size);
            for (int _i62 = 0; _i62 < _list61.size; ++_i62)
            {
              TResult _elem63; // optional
              _elem63 = new TResult();
              _elem63.read(iprot);
              struct.success.add(_elem63);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class put_args implements org.apache.thrift.TBase<put_args, put_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("put_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PUT_FIELD_DESC = new org.apache.thrift.protocol.TField("put", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new put_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new put_argsTupleSchemeFactory());
    }

    /**
     * the table to put data in
     */
    public ByteBuffer table; // required
    /**
     * the TPut to put
     */
    public TPut put; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to put data in
       */
      TABLE((short)1, "table"),
      /**
       * the TPut to put
       */
      PUT((short)2, "put");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // PUT
            return PUT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.PUT, new org.apache.thrift.meta_data.FieldMetaData("put", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TPut.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(put_args.class, metaDataMap);
    }

    public put_args() {
    }

    public put_args(
      ByteBuffer table,
      TPut put)
    {
      this();
      this.table = table;
      this.put = put;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public put_args(put_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetPut()) {
        this.put = new TPut(other.put);
      }
    }

    public put_args deepCopy() {
      return new put_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.put = null;
    }

    /**
     * the table to put data in
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to put data in
     */
    public put_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public put_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * the TPut to put
     */
    public TPut getPut() {
      return this.put;
    }

    /**
     * the TPut to put
     */
    public put_args setPut(TPut put) {
      this.put = put;
      return this;
    }

    public void unsetPut() {
      this.put = null;
    }

    /** Returns true if field put is set (has been assigned a value) and false otherwise */
    public boolean isSetPut() {
      return this.put != null;
    }

    public void setPutIsSet(boolean value) {
      if (!value) {
        this.put = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case PUT:
        if (value == null) {
          unsetPut();
        } else {
          setPut((TPut)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case PUT:
        return getPut();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case PUT:
        return isSetPut();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof put_args)
        return this.equals((put_args)that);
      return false;
    }

    public boolean equals(put_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_put = true && this.isSetPut();
      boolean that_present_put = true && that.isSetPut();
      if (this_present_put || that_present_put) {
        if (!(this_present_put && that_present_put))
          return false;
        if (!this.put.equals(that.put))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(put_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      put_args typedOther = (put_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPut()).compareTo(typedOther.isSetPut());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPut()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.put, typedOther.put);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("put_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("put:");
      if (this.put == null) {
        sb.append("null");
      } else {
        sb.append(this.put);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (put == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'put' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class put_argsStandardSchemeFactory implements SchemeFactory {
      public put_argsStandardScheme getScheme() {
        return new put_argsStandardScheme();
      }
    }

    private static class put_argsStandardScheme extends StandardScheme<put_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, put_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PUT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.put = new TPut();
                struct.put.read(iprot);
                struct.setPutIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, put_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.put != null) {
          oprot.writeFieldBegin(PUT_FIELD_DESC);
          struct.put.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class put_argsTupleSchemeFactory implements SchemeFactory {
      public put_argsTupleScheme getScheme() {
        return new put_argsTupleScheme();
      }
    }

    private static class put_argsTupleScheme extends TupleScheme<put_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, put_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        struct.put.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, put_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.put = new TPut();
        struct.put.read(iprot);
        struct.setPutIsSet(true);
      }
    }

  }

  public static class put_result implements org.apache.thrift.TBase<put_result, put_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("put_result");

    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new put_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new put_resultTupleSchemeFactory());
    }

    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(put_result.class, metaDataMap);
    }

    public put_result() {
    }

    public put_result(
      TIOError io)
    {
      this();
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public put_result(put_result other) {
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public put_result deepCopy() {
      return new put_result(this);
    }

    @Override
    public void clear() {
      this.io = null;
    }

    public TIOError getIo() {
      return this.io;
    }

    public put_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof put_result)
        return this.equals((put_result)that);
      return false;
    }

    public boolean equals(put_result that) {
      if (that == null)
        return false;

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(put_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      put_result typedOther = (put_result)other;

      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("put_result(");
      boolean first = true;

      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class put_resultStandardSchemeFactory implements SchemeFactory {
      public put_resultStandardScheme getScheme() {
        return new put_resultStandardScheme();
      }
    }

    private static class put_resultStandardScheme extends StandardScheme<put_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, put_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, put_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class put_resultTupleSchemeFactory implements SchemeFactory {
      public put_resultTupleScheme getScheme() {
        return new put_resultTupleScheme();
      }
    }

    private static class put_resultTupleScheme extends TupleScheme<put_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, put_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIo()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, put_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class checkAndPut_args implements org.apache.thrift.TBase<checkAndPut_args, checkAndPut_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkAndPut_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("family", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField QUALIFIER_FIELD_DESC = new org.apache.thrift.protocol.TField("qualifier", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)5);
    private static final org.apache.thrift.protocol.TField PUT_FIELD_DESC = new org.apache.thrift.protocol.TField("put", org.apache.thrift.protocol.TType.STRUCT, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new checkAndPut_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new checkAndPut_argsTupleSchemeFactory());
    }

    /**
     * to check in and put to
     */
    public ByteBuffer table; // required
    /**
     * row to check
     */
    public ByteBuffer row; // required
    /**
     * column family to check
     */
    public ByteBuffer family; // required
    /**
     * column qualifier to check
     */
    public ByteBuffer qualifier; // required
    /**
     * the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     */
    public ByteBuffer value; // required
    /**
     * the TPut to put if the check succeeds
     */
    public TPut put; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * to check in and put to
       */
      TABLE((short)1, "table"),
      /**
       * row to check
       */
      ROW((short)2, "row"),
      /**
       * column family to check
       */
      FAMILY((short)3, "family"),
      /**
       * column qualifier to check
       */
      QUALIFIER((short)4, "qualifier"),
      /**
       * the expected value, if not provided the
       * check is for the non-existence of the
       * column in question
       */
      VALUE((short)5, "value"),
      /**
       * the TPut to put if the check succeeds
       */
      PUT((short)6, "put");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // ROW
            return ROW;
          case 3: // FAMILY
            return FAMILY;
          case 4: // QUALIFIER
            return QUALIFIER;
          case 5: // VALUE
            return VALUE;
          case 6: // PUT
            return PUT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.FAMILY, new org.apache.thrift.meta_data.FieldMetaData("family", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.QUALIFIER, new org.apache.thrift.meta_data.FieldMetaData("qualifier", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.PUT, new org.apache.thrift.meta_data.FieldMetaData("put", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TPut.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkAndPut_args.class, metaDataMap);
    }

    public checkAndPut_args() {
    }

    public checkAndPut_args(
      ByteBuffer table,
      ByteBuffer row,
      ByteBuffer family,
      ByteBuffer qualifier,
      ByteBuffer value,
      TPut put)
    {
      this();
      this.table = table;
      this.row = row;
      this.family = family;
      this.qualifier = qualifier;
      this.value = value;
      this.put = put;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkAndPut_args(checkAndPut_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetRow()) {
        this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
;
      }
      if (other.isSetFamily()) {
        this.family = org.apache.thrift.TBaseHelper.copyBinary(other.family);
;
      }
      if (other.isSetQualifier()) {
        this.qualifier = org.apache.thrift.TBaseHelper.copyBinary(other.qualifier);
;
      }
      if (other.isSetValue()) {
        this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
;
      }
      if (other.isSetPut()) {
        this.put = new TPut(other.put);
      }
    }

    public checkAndPut_args deepCopy() {
      return new checkAndPut_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.row = null;
      this.family = null;
      this.qualifier = null;
      this.value = null;
      this.put = null;
    }

    /**
     * to check in and put to
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * to check in and put to
     */
    public checkAndPut_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public checkAndPut_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * row to check
     */
    public byte[] getRow() {
      setRow(org.apache.thrift.TBaseHelper.rightSize(row));
      return row == null ? null : row.array();
    }

    public ByteBuffer bufferForRow() {
      return row;
    }

    /**
     * row to check
     */
    public checkAndPut_args setRow(byte[] row) {
      setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row));
      return this;
    }

    public checkAndPut_args setRow(ByteBuffer row) {
      this.row = row;
      return this;
    }

    public void unsetRow() {
      this.row = null;
    }

    /** Returns true if field row is set (has been assigned a value) and false otherwise */
    public boolean isSetRow() {
      return this.row != null;
    }

    public void setRowIsSet(boolean value) {
      if (!value) {
        this.row = null;
      }
    }

    /**
     * column family to check
     */
    public byte[] getFamily() {
      setFamily(org.apache.thrift.TBaseHelper.rightSize(family));
      return family == null ? null : family.array();
    }

    public ByteBuffer bufferForFamily() {
      return family;
    }

    /**
     * column family to check
     */
    public checkAndPut_args setFamily(byte[] family) {
      setFamily(family == null ? (ByteBuffer)null : ByteBuffer.wrap(family));
      return this;
    }

    public checkAndPut_args setFamily(ByteBuffer family) {
      this.family = family;
      return this;
    }

    public void unsetFamily() {
      this.family = null;
    }

    /** Returns true if field family is set (has been assigned a value) and false otherwise */
    public boolean isSetFamily() {
      return this.family != null;
    }

    public void setFamilyIsSet(boolean value) {
      if (!value) {
        this.family = null;
      }
    }

    /**
     * column qualifier to check
     */
    public byte[] getQualifier() {
      setQualifier(org.apache.thrift.TBaseHelper.rightSize(qualifier));
      return qualifier == null ? null : qualifier.array();
    }

    public ByteBuffer bufferForQualifier() {
      return qualifier;
    }

    /**
     * column qualifier to check
     */
    public checkAndPut_args setQualifier(byte[] qualifier) {
      setQualifier(qualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(qualifier));
      return this;
    }

    public checkAndPut_args setQualifier(ByteBuffer qualifier) {
      this.qualifier = qualifier;
      return this;
    }

    public void unsetQualifier() {
      this.qualifier = null;
    }

    /** Returns true if field qualifier is set (has been assigned a value) and false otherwise */
    public boolean isSetQualifier() {
      return this.qualifier != null;
    }

    public void setQualifierIsSet(boolean value) {
      if (!value) {
        this.qualifier = null;
      }
    }

    /**
     * the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     */
    public byte[] getValue() {
      setValue(org.apache.thrift.TBaseHelper.rightSize(value));
      return value == null ? null : value.array();
    }

    public ByteBuffer bufferForValue() {
      return value;
    }

    /**
     * the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     */
    public checkAndPut_args setValue(byte[] value) {
      setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value));
      return this;
    }

    public checkAndPut_args setValue(ByteBuffer value) {
      this.value = value;
      return this;
    }

    public void unsetValue() {
      this.value = null;
    }

    /** Returns true if field value is set (has been assigned a value) and false otherwise */
    public boolean isSetValue() {
      return this.value != null;
    }

    public void setValueIsSet(boolean value) {
      if (!value) {
        this.value = null;
      }
    }

    /**
     * the TPut to put if the check succeeds
     */
    public TPut getPut() {
      return this.put;
    }

    /**
     * the TPut to put if the check succeeds
     */
    public checkAndPut_args setPut(TPut put) {
      this.put = put;
      return this;
    }

    public void unsetPut() {
      this.put = null;
    }

    /** Returns true if field put is set (has been assigned a value) and false otherwise */
    public boolean isSetPut() {
      return this.put != null;
    }

    public void setPutIsSet(boolean value) {
      if (!value) {
        this.put = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case ROW:
        if (value == null) {
          unsetRow();
        } else {
          setRow((ByteBuffer)value);
        }
        break;

      case FAMILY:
        if (value == null) {
          unsetFamily();
        } else {
          setFamily((ByteBuffer)value);
        }
        break;

      case QUALIFIER:
        if (value == null) {
          unsetQualifier();
        } else {
          setQualifier((ByteBuffer)value);
        }
        break;

      case VALUE:
        if (value == null) {
          unsetValue();
        } else {
          setValue((ByteBuffer)value);
        }
        break;

      case PUT:
        if (value == null) {
          unsetPut();
        } else {
          setPut((TPut)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case ROW:
        return getRow();

      case FAMILY:
        return getFamily();

      case QUALIFIER:
        return getQualifier();

      case VALUE:
        return getValue();

      case PUT:
        return getPut();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case ROW:
        return isSetRow();
      case FAMILY:
        return isSetFamily();
      case QUALIFIER:
        return isSetQualifier();
      case VALUE:
        return isSetValue();
      case PUT:
        return isSetPut();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof checkAndPut_args)
        return this.equals((checkAndPut_args)that);
      return false;
    }

    public boolean equals(checkAndPut_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_row = true && this.isSetRow();
      boolean that_present_row = true && that.isSetRow();
      if (this_present_row || that_present_row) {
        if (!(this_present_row && that_present_row))
          return false;
        if (!this.row.equals(that.row))
          return false;
      }

      boolean this_present_family = true && this.isSetFamily();
      boolean that_present_family = true && that.isSetFamily();
      if (this_present_family || that_present_family) {
        if (!(this_present_family && that_present_family))
          return false;
        if (!this.family.equals(that.family))
          return false;
      }

      boolean this_present_qualifier = true && this.isSetQualifier();
      boolean that_present_qualifier = true && that.isSetQualifier();
      if (this_present_qualifier || that_present_qualifier) {
        if (!(this_present_qualifier && that_present_qualifier))
          return false;
        if (!this.qualifier.equals(that.qualifier))
          return false;
      }

      boolean this_present_value = true && this.isSetValue();
      boolean that_present_value = true && that.isSetValue();
      if (this_present_value || that_present_value) {
        if (!(this_present_value && that_present_value))
          return false;
        if (!this.value.equals(that.value))
          return false;
      }

      boolean this_present_put = true && this.isSetPut();
      boolean that_present_put = true && that.isSetPut();
      if (this_present_put || that_present_put) {
        if (!(this_present_put && that_present_put))
          return false;
        if (!this.put.equals(that.put))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(checkAndPut_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      checkAndPut_args typedOther = (checkAndPut_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetRow()).compareTo(typedOther.isSetRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.row, typedOther.row);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetFamily()).compareTo(typedOther.isSetFamily());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFamily()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.family, typedOther.family);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetQualifier()).compareTo(typedOther.isSetQualifier());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQualifier()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.qualifier, typedOther.qualifier);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetValue()).compareTo(typedOther.isSetValue());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValue()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, typedOther.value);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPut()).compareTo(typedOther.isSetPut());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPut()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.put, typedOther.put);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("checkAndPut_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("row:");
      if (this.row == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.row, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("family:");
      if (this.family == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.family, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("qualifier:");
      if (this.qualifier == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.qualifier, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.value, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("put:");
      if (this.put == null) {
        sb.append("null");
      } else {
        sb.append(this.put);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (row == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'row' was not present! Struct: " + toString());
      }
      if (family == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'family' was not present! Struct: " + toString());
      }
      if (qualifier == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'qualifier' was not present! Struct: " + toString());
      }
      if (put == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'put' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkAndPut_argsStandardSchemeFactory implements SchemeFactory {
      public checkAndPut_argsStandardScheme getScheme() {
        return new checkAndPut_argsStandardScheme();
      }
    }

    private static class checkAndPut_argsStandardScheme extends StandardScheme<checkAndPut_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, checkAndPut_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.row = iprot.readBinary();
                struct.setRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // FAMILY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.family = iprot.readBinary();
                struct.setFamilyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // QUALIFIER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.qualifier = iprot.readBinary();
                struct.setQualifierIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // VALUE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.value = iprot.readBinary();
                struct.setValueIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // PUT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.put = new TPut();
                struct.put.read(iprot);
                struct.setPutIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkAndPut_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.row != null) {
          oprot.writeFieldBegin(ROW_FIELD_DESC);
          oprot.writeBinary(struct.row);
          oprot.writeFieldEnd();
        }
        if (struct.family != null) {
          oprot.writeFieldBegin(FAMILY_FIELD_DESC);
          oprot.writeBinary(struct.family);
          oprot.writeFieldEnd();
        }
        if (struct.qualifier != null) {
          oprot.writeFieldBegin(QUALIFIER_FIELD_DESC);
          oprot.writeBinary(struct.qualifier);
          oprot.writeFieldEnd();
        }
        if (struct.value != null) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeBinary(struct.value);
          oprot.writeFieldEnd();
        }
        if (struct.put != null) {
          oprot.writeFieldBegin(PUT_FIELD_DESC);
          struct.put.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkAndPut_argsTupleSchemeFactory implements SchemeFactory {
      public checkAndPut_argsTupleScheme getScheme() {
        return new checkAndPut_argsTupleScheme();
      }
    }

    private static class checkAndPut_argsTupleScheme extends TupleScheme<checkAndPut_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, checkAndPut_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        oprot.writeBinary(struct.row);
        oprot.writeBinary(struct.family);
        oprot.writeBinary(struct.qualifier);
        struct.put.write(oprot);
        BitSet optionals = new BitSet();
        if (struct.isSetValue()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetValue()) {
          oprot.writeBinary(struct.value);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkAndPut_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.row = iprot.readBinary();
        struct.setRowIsSet(true);
        struct.family = iprot.readBinary();
        struct.setFamilyIsSet(true);
        struct.qualifier = iprot.readBinary();
        struct.setQualifierIsSet(true);
        struct.put = new TPut();
        struct.put.read(iprot);
        struct.setPutIsSet(true);
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.value = iprot.readBinary();
          struct.setValueIsSet(true);
        }
      }
    }

  }

  public static class checkAndPut_result implements org.apache.thrift.TBase<checkAndPut_result, checkAndPut_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkAndPut_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new checkAndPut_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new checkAndPut_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private BitSet __isset_bit_vector = new BitSet(1);
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkAndPut_result.class, metaDataMap);
    }

    public checkAndPut_result() {
    }

    public checkAndPut_result(
      boolean success,
      TIOError io)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkAndPut_result(checkAndPut_result other) {
      __isset_bit_vector.clear();
      __isset_bit_vector.or(other.__isset_bit_vector);
      this.success = other.success;
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public checkAndPut_result deepCopy() {
      return new checkAndPut_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.io = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public checkAndPut_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
    }

    public TIOError getIo() {
      return this.io;
    }

    public checkAndPut_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof checkAndPut_result)
        return this.equals((checkAndPut_result)that);
      return false;
    }

    public boolean equals(checkAndPut_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(checkAndPut_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      checkAndPut_result typedOther = (checkAndPut_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("checkAndPut_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkAndPut_resultStandardSchemeFactory implements SchemeFactory {
      public checkAndPut_resultStandardScheme getScheme() {
        return new checkAndPut_resultStandardScheme();
      }
    }

    private static class checkAndPut_resultStandardScheme extends StandardScheme<checkAndPut_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, checkAndPut_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkAndPut_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
        oprot.writeBool(struct.success);
        oprot.writeFieldEnd();
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkAndPut_resultTupleSchemeFactory implements SchemeFactory {
      public checkAndPut_resultTupleScheme getScheme() {
        return new checkAndPut_resultTupleScheme();
      }
    }

    private static class checkAndPut_resultTupleScheme extends TupleScheme<checkAndPut_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, checkAndPut_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkAndPut_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class putMultiple_args implements org.apache.thrift.TBase<putMultiple_args, putMultiple_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("putMultiple_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("puts", org.apache.thrift.protocol.TType.LIST, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new putMultiple_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new putMultiple_argsTupleSchemeFactory());
    }

    /**
     * the table to put data in
     */
    public ByteBuffer table; // required
    /**
     * a list of TPuts to commit
     */
    public List<TPut> puts; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to put data in
       */
      TABLE((short)1, "table"),
      /**
       * a list of TPuts to commit
       */
      PUTS((short)2, "puts");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // PUTS
            return PUTS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.PUTS, new org.apache.thrift.meta_data.FieldMetaData("puts", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TPut.class))));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(putMultiple_args.class, metaDataMap);
    }

    public putMultiple_args() {
    }

    public putMultiple_args(
      ByteBuffer table,
      List<TPut> puts)
    {
      this();
      this.table = table;
      this.puts = puts;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public putMultiple_args(putMultiple_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetPuts()) {
        List<TPut> __this__puts = new ArrayList<TPut>();
        for (TPut other_element : other.puts) {
          __this__puts.add(new TPut(other_element));
        }
        this.puts = __this__puts;
      }
    }

    public putMultiple_args deepCopy() {
      return new putMultiple_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.puts = null;
    }

    /**
     * the table to put data in
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to put data in
     */
    public putMultiple_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public putMultiple_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    public int getPutsSize() {
      return (this.puts == null) ? 0 : this.puts.size();
    }

    public java.util.Iterator<TPut> getPutsIterator() {
      return (this.puts == null) ? null : this.puts.iterator();
    }

    public void addToPuts(TPut elem) {
      if (this.puts == null) {
        this.puts = new ArrayList<TPut>();
      }
      this.puts.add(elem);
    }

    /**
     * a list of TPuts to commit
     */
    public List<TPut> getPuts() {
      return this.puts;
    }

    /**
     * a list of TPuts to commit
     */
    public putMultiple_args setPuts(List<TPut> puts) {
      this.puts = puts;
      return this;
    }

    public void unsetPuts() {
      this.puts = null;
    }

    /** Returns true if field puts is set (has been assigned a value) and false otherwise */
    public boolean isSetPuts() {
      return this.puts != null;
    }

    public void setPutsIsSet(boolean value) {
      if (!value) {
        this.puts = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case PUTS:
        if (value == null) {
          unsetPuts();
        } else {
          setPuts((List<TPut>)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case PUTS:
        return getPuts();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case PUTS:
        return isSetPuts();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof putMultiple_args)
        return this.equals((putMultiple_args)that);
      return false;
    }

    public boolean equals(putMultiple_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_puts = true && this.isSetPuts();
      boolean that_present_puts = true && that.isSetPuts();
      if (this_present_puts || that_present_puts) {
        if (!(this_present_puts && that_present_puts))
          return false;
        if (!this.puts.equals(that.puts))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(putMultiple_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      putMultiple_args typedOther = (putMultiple_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPuts()).compareTo(typedOther.isSetPuts());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPuts()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.puts, typedOther.puts);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("putMultiple_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("puts:");
      if (this.puts == null) {
        sb.append("null");
      } else {
        sb.append(this.puts);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (puts == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'puts' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class putMultiple_argsStandardSchemeFactory implements SchemeFactory {
      public putMultiple_argsStandardScheme getScheme() {
        return new putMultiple_argsStandardScheme();
      }
    }

    private static class putMultiple_argsStandardScheme extends StandardScheme<putMultiple_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, putMultiple_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PUTS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list64 = iprot.readListBegin();
                  struct.puts = new ArrayList<TPut>(_list64.size);
                  for (int _i65 = 0; _i65 < _list64.size; ++_i65)
                  {
                    TPut _elem66; // optional
                    _elem66 = new TPut();
                    _elem66.read(iprot);
                    struct.puts.add(_elem66);
                  }
                  iprot.readListEnd();
                }
                struct.setPutsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, putMultiple_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.puts != null) {
          oprot.writeFieldBegin(PUTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.puts.size()));
            for (TPut _iter67 : struct.puts)
            {
              _iter67.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class putMultiple_argsTupleSchemeFactory implements SchemeFactory {
      public putMultiple_argsTupleScheme getScheme() {
        return new putMultiple_argsTupleScheme();
      }
    }

    private static class putMultiple_argsTupleScheme extends TupleScheme<putMultiple_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, putMultiple_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        {
          oprot.writeI32(struct.puts.size());
          for (TPut _iter68 : struct.puts)
          {
            _iter68.write(oprot);
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, putMultiple_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        {
          org.apache.thrift.protocol.TList _list69 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.puts = new ArrayList<TPut>(_list69.size);
          for (int _i70 = 0; _i70 < _list69.size; ++_i70)
          {
            TPut _elem71; // optional
            _elem71 = new TPut();
            _elem71.read(iprot);
            struct.puts.add(_elem71);
          }
        }
        struct.setPutsIsSet(true);
      }
    }

  }

  public static class putMultiple_result implements org.apache.thrift.TBase<putMultiple_result, putMultiple_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("putMultiple_result");

    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new putMultiple_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new putMultiple_resultTupleSchemeFactory());
    }

    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(putMultiple_result.class, metaDataMap);
    }

    public putMultiple_result() {
    }

    public putMultiple_result(
      TIOError io)
    {
      this();
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public putMultiple_result(putMultiple_result other) {
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public putMultiple_result deepCopy() {
      return new putMultiple_result(this);
    }

    @Override
    public void clear() {
      this.io = null;
    }

    public TIOError getIo() {
      return this.io;
    }

    public putMultiple_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof putMultiple_result)
        return this.equals((putMultiple_result)that);
      return false;
    }

    public boolean equals(putMultiple_result that) {
      if (that == null)
        return false;

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(putMultiple_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      putMultiple_result typedOther = (putMultiple_result)other;

      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("putMultiple_result(");
      boolean first = true;

      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class putMultiple_resultStandardSchemeFactory implements SchemeFactory {
      public putMultiple_resultStandardScheme getScheme() {
        return new putMultiple_resultStandardScheme();
      }
    }

    private static class putMultiple_resultStandardScheme extends StandardScheme<putMultiple_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, putMultiple_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, putMultiple_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class putMultiple_resultTupleSchemeFactory implements SchemeFactory {
      public putMultiple_resultTupleScheme getScheme() {
        return new putMultiple_resultTupleScheme();
      }
    }

    private static class putMultiple_resultTupleScheme extends TupleScheme<putMultiple_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, putMultiple_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIo()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, putMultiple_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class deleteSingle_args implements org.apache.thrift.TBase<deleteSingle_args, deleteSingle_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteSingle_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField DELETE_SINGLE_FIELD_DESC = new org.apache.thrift.protocol.TField("deleteSingle", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteSingle_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteSingle_argsTupleSchemeFactory());
    }

    /**
     * the table to delete from
     */
    public ByteBuffer table; // required
    /**
     * the TDelete to delete
     */
    public TDelete deleteSingle; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to delete from
       */
      TABLE((short)1, "table"),
      /**
       * the TDelete to delete
       */
      DELETE_SINGLE((short)2, "deleteSingle");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // DELETE_SINGLE
            return DELETE_SINGLE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.DELETE_SINGLE, new org.apache.thrift.meta_data.FieldMetaData("deleteSingle", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TDelete.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteSingle_args.class, metaDataMap);
    }

    public deleteSingle_args() {
    }

    public deleteSingle_args(
      ByteBuffer table,
      TDelete deleteSingle)
    {
      this();
      this.table = table;
      this.deleteSingle = deleteSingle;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteSingle_args(deleteSingle_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetDeleteSingle()) {
        this.deleteSingle = new TDelete(other.deleteSingle);
      }
    }

    public deleteSingle_args deepCopy() {
      return new deleteSingle_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.deleteSingle = null;
    }

    /**
     * the table to delete from
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to delete from
     */
    public deleteSingle_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public deleteSingle_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * the TDelete to delete
     */
    public TDelete getDeleteSingle() {
      return this.deleteSingle;
    }

    /**
     * the TDelete to delete
     */
    public deleteSingle_args setDeleteSingle(TDelete deleteSingle) {
      this.deleteSingle = deleteSingle;
      return this;
    }

    public void unsetDeleteSingle() {
      this.deleteSingle = null;
    }

    /** Returns true if field deleteSingle is set (has been assigned a value) and false otherwise */
    public boolean isSetDeleteSingle() {
      return this.deleteSingle != null;
    }

    public void setDeleteSingleIsSet(boolean value) {
      if (!value) {
        this.deleteSingle = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case DELETE_SINGLE:
        if (value == null) {
          unsetDeleteSingle();
        } else {
          setDeleteSingle((TDelete)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case DELETE_SINGLE:
        return getDeleteSingle();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case DELETE_SINGLE:
        return isSetDeleteSingle();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteSingle_args)
        return this.equals((deleteSingle_args)that);
      return false;
    }

    public boolean equals(deleteSingle_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_deleteSingle = true && this.isSetDeleteSingle();
      boolean that_present_deleteSingle = true && that.isSetDeleteSingle();
      if (this_present_deleteSingle || that_present_deleteSingle) {
        if (!(this_present_deleteSingle && that_present_deleteSingle))
          return false;
        if (!this.deleteSingle.equals(that.deleteSingle))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(deleteSingle_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      deleteSingle_args typedOther = (deleteSingle_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDeleteSingle()).compareTo(typedOther.isSetDeleteSingle());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDeleteSingle()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.deleteSingle, typedOther.deleteSingle);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteSingle_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("deleteSingle:");
      if (this.deleteSingle == null) {
        sb.append("null");
      } else {
        sb.append(this.deleteSingle);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (deleteSingle == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'deleteSingle' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteSingle_argsStandardSchemeFactory implements SchemeFactory {
      public deleteSingle_argsStandardScheme getScheme() {
        return new deleteSingle_argsStandardScheme();
      }
    }

    private static class deleteSingle_argsStandardScheme extends StandardScheme<deleteSingle_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteSingle_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // DELETE_SINGLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.deleteSingle = new TDelete();
                struct.deleteSingle.read(iprot);
                struct.setDeleteSingleIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteSingle_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.deleteSingle != null) {
          oprot.writeFieldBegin(DELETE_SINGLE_FIELD_DESC);
          struct.deleteSingle.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteSingle_argsTupleSchemeFactory implements SchemeFactory {
      public deleteSingle_argsTupleScheme getScheme() {
        return new deleteSingle_argsTupleScheme();
      }
    }

    private static class deleteSingle_argsTupleScheme extends TupleScheme<deleteSingle_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteSingle_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        struct.deleteSingle.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteSingle_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.deleteSingle = new TDelete();
        struct.deleteSingle.read(iprot);
        struct.setDeleteSingleIsSet(true);
      }
    }

  }

  public static class deleteSingle_result implements org.apache.thrift.TBase<deleteSingle_result, deleteSingle_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteSingle_result");

    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteSingle_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteSingle_resultTupleSchemeFactory());
    }

    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteSingle_result.class, metaDataMap);
    }

    public deleteSingle_result() {
    }

    public deleteSingle_result(
      TIOError io)
    {
      this();
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteSingle_result(deleteSingle_result other) {
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public deleteSingle_result deepCopy() {
      return new deleteSingle_result(this);
    }

    @Override
    public void clear() {
      this.io = null;
    }

    public TIOError getIo() {
      return this.io;
    }

    public deleteSingle_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteSingle_result)
        return this.equals((deleteSingle_result)that);
      return false;
    }

    public boolean equals(deleteSingle_result that) {
      if (that == null)
        return false;

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(deleteSingle_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      deleteSingle_result typedOther = (deleteSingle_result)other;

      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteSingle_result(");
      boolean first = true;

      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteSingle_resultStandardSchemeFactory implements SchemeFactory {
      public deleteSingle_resultStandardScheme getScheme() {
        return new deleteSingle_resultStandardScheme();
      }
    }

    private static class deleteSingle_resultStandardScheme extends StandardScheme<deleteSingle_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteSingle_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteSingle_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteSingle_resultTupleSchemeFactory implements SchemeFactory {
      public deleteSingle_resultTupleScheme getScheme() {
        return new deleteSingle_resultTupleScheme();
      }
    }

    private static class deleteSingle_resultTupleScheme extends TupleScheme<deleteSingle_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteSingle_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIo()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteSingle_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class deleteMultiple_args implements org.apache.thrift.TBase<deleteMultiple_args, deleteMultiple_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteMultiple_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField DELETES_FIELD_DESC = new org.apache.thrift.protocol.TField("deletes", org.apache.thrift.protocol.TType.LIST, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteMultiple_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteMultiple_argsTupleSchemeFactory());
    }

    /**
     * the table to delete from
     */
    public ByteBuffer table; // required
    /**
     * list of TDeletes to delete
     */
    public List<TDelete> deletes; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to delete from
       */
      TABLE((short)1, "table"),
      /**
       * list of TDeletes to delete
       */
      DELETES((short)2, "deletes");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // DELETES
            return DELETES;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.DELETES, new org.apache.thrift.meta_data.FieldMetaData("deletes", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TDelete.class))));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteMultiple_args.class, metaDataMap);
    }

    public deleteMultiple_args() {
    }

    public deleteMultiple_args(
      ByteBuffer table,
      List<TDelete> deletes)
    {
      this();
      this.table = table;
      this.deletes = deletes;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteMultiple_args(deleteMultiple_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetDeletes()) {
        List<TDelete> __this__deletes = new ArrayList<TDelete>();
        for (TDelete other_element : other.deletes) {
          __this__deletes.add(new TDelete(other_element));
        }
        this.deletes = __this__deletes;
      }
    }

    public deleteMultiple_args deepCopy() {
      return new deleteMultiple_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.deletes = null;
    }

    /**
     * the table to delete from
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to delete from
     */
    public deleteMultiple_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public deleteMultiple_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    public int getDeletesSize() {
      return (this.deletes == null) ? 0 : this.deletes.size();
    }

    public java.util.Iterator<TDelete> getDeletesIterator() {
      return (this.deletes == null) ? null : this.deletes.iterator();
    }

    public void addToDeletes(TDelete elem) {
      if (this.deletes == null) {
        this.deletes = new ArrayList<TDelete>();
      }
      this.deletes.add(elem);
    }

    /**
     * list of TDeletes to delete
     */
    public List<TDelete> getDeletes() {
      return this.deletes;
    }

    /**
     * list of TDeletes to delete
     */
    public deleteMultiple_args setDeletes(List<TDelete> deletes) {
      this.deletes = deletes;
      return this;
    }

    public void unsetDeletes() {
      this.deletes = null;
    }

    /** Returns true if field deletes is set (has been assigned a value) and false otherwise */
    public boolean isSetDeletes() {
      return this.deletes != null;
    }

    public void setDeletesIsSet(boolean value) {
      if (!value) {
        this.deletes = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case DELETES:
        if (value == null) {
          unsetDeletes();
        } else {
          setDeletes((List<TDelete>)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case DELETES:
        return getDeletes();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case DELETES:
        return isSetDeletes();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteMultiple_args)
        return this.equals((deleteMultiple_args)that);
      return false;
    }

    public boolean equals(deleteMultiple_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_deletes = true && this.isSetDeletes();
      boolean that_present_deletes = true && that.isSetDeletes();
      if (this_present_deletes || that_present_deletes) {
        if (!(this_present_deletes && that_present_deletes))
          return false;
        if (!this.deletes.equals(that.deletes))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(deleteMultiple_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      deleteMultiple_args typedOther = (deleteMultiple_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDeletes()).compareTo(typedOther.isSetDeletes());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDeletes()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.deletes, typedOther.deletes);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteMultiple_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("deletes:");
      if (this.deletes == null) {
        sb.append("null");
      } else {
        sb.append(this.deletes);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (deletes == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'deletes' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteMultiple_argsStandardSchemeFactory implements SchemeFactory {
      public deleteMultiple_argsStandardScheme getScheme() {
        return new deleteMultiple_argsStandardScheme();
      }
    }

    private static class deleteMultiple_argsStandardScheme extends StandardScheme<deleteMultiple_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteMultiple_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // DELETES
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list72 = iprot.readListBegin();
                  struct.deletes = new ArrayList<TDelete>(_list72.size);
                  for (int _i73 = 0; _i73 < _list72.size; ++_i73)
                  {
                    TDelete _elem74; // optional
                    _elem74 = new TDelete();
                    _elem74.read(iprot);
                    struct.deletes.add(_elem74);
                  }
                  iprot.readListEnd();
                }
                struct.setDeletesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteMultiple_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.deletes != null) {
          oprot.writeFieldBegin(DELETES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.deletes.size()));
            for (TDelete _iter75 : struct.deletes)
            {
              _iter75.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteMultiple_argsTupleSchemeFactory implements SchemeFactory {
      public deleteMultiple_argsTupleScheme getScheme() {
        return new deleteMultiple_argsTupleScheme();
      }
    }

    private static class deleteMultiple_argsTupleScheme extends TupleScheme<deleteMultiple_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteMultiple_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        {
          oprot.writeI32(struct.deletes.size());
          for (TDelete _iter76 : struct.deletes)
          {
            _iter76.write(oprot);
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteMultiple_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        {
          org.apache.thrift.protocol.TList _list77 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.deletes = new ArrayList<TDelete>(_list77.size);
          for (int _i78 = 0; _i78 < _list77.size; ++_i78)
          {
            TDelete _elem79; // optional
            _elem79 = new TDelete();
            _elem79.read(iprot);
            struct.deletes.add(_elem79);
          }
        }
        struct.setDeletesIsSet(true);
      }
    }

  }

  public static class deleteMultiple_result implements org.apache.thrift.TBase<deleteMultiple_result, deleteMultiple_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteMultiple_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new deleteMultiple_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new deleteMultiple_resultTupleSchemeFactory());
    }

    public List<TDelete> success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TDelete.class))));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteMultiple_result.class, metaDataMap);
    }

    public deleteMultiple_result() {
    }

    public deleteMultiple_result(
      List<TDelete> success,
      TIOError io)
    {
      this();
      this.success = success;
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteMultiple_result(deleteMultiple_result other) {
      if (other.isSetSuccess()) {
        List<TDelete> __this__success = new ArrayList<TDelete>();
        for (TDelete other_element : other.success) {
          __this__success.add(new TDelete(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public deleteMultiple_result deepCopy() {
      return new deleteMultiple_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.io = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<TDelete> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(TDelete elem) {
      if (this.success == null) {
        this.success = new ArrayList<TDelete>();
      }
      this.success.add(elem);
    }

    public List<TDelete> getSuccess() {
      return this.success;
    }

    public deleteMultiple_result setSuccess(List<TDelete> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public TIOError getIo() {
      return this.io;
    }

    public deleteMultiple_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<TDelete>)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteMultiple_result)
        return this.equals((deleteMultiple_result)that);
      return false;
    }

    public boolean equals(deleteMultiple_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(deleteMultiple_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      deleteMultiple_result typedOther = (deleteMultiple_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("deleteMultiple_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteMultiple_resultStandardSchemeFactory implements SchemeFactory {
      public deleteMultiple_resultStandardScheme getScheme() {
        return new deleteMultiple_resultStandardScheme();
      }
    }

    private static class deleteMultiple_resultStandardScheme extends StandardScheme<deleteMultiple_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteMultiple_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list80 = iprot.readListBegin();
                  struct.success = new ArrayList<TDelete>(_list80.size);
                  for (int _i81 = 0; _i81 < _list80.size; ++_i81)
                  {
                    TDelete _elem82; // optional
                    _elem82 = new TDelete();
                    _elem82.read(iprot);
                    struct.success.add(_elem82);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteMultiple_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (TDelete _iter83 : struct.success)
            {
              _iter83.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteMultiple_resultTupleSchemeFactory implements SchemeFactory {
      public deleteMultiple_resultTupleScheme getScheme() {
        return new deleteMultiple_resultTupleScheme();
      }
    }

    private static class deleteMultiple_resultTupleScheme extends TupleScheme<deleteMultiple_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteMultiple_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (TDelete _iter84 : struct.success)
            {
              _iter84.write(oprot);
            }
          }
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteMultiple_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list85 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<TDelete>(_list85.size);
            for (int _i86 = 0; _i86 < _list85.size; ++_i86)
            {
              TDelete _elem87; // optional
              _elem87 = new TDelete();
              _elem87.read(iprot);
              struct.success.add(_elem87);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class checkAndDelete_args implements org.apache.thrift.TBase<checkAndDelete_args, checkAndDelete_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkAndDelete_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("family", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField QUALIFIER_FIELD_DESC = new org.apache.thrift.protocol.TField("qualifier", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)5);
    private static final org.apache.thrift.protocol.TField DELETE_SINGLE_FIELD_DESC = new org.apache.thrift.protocol.TField("deleteSingle", org.apache.thrift.protocol.TType.STRUCT, (short)6);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new checkAndDelete_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new checkAndDelete_argsTupleSchemeFactory());
    }

    /**
     * to check in and delete from
     */
    public ByteBuffer table; // required
    /**
     * row to check
     */
    public ByteBuffer row; // required
    /**
     * column family to check
     */
    public ByteBuffer family; // required
    /**
     * column qualifier to check
     */
    public ByteBuffer qualifier; // required
    /**
     * the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     */
    public ByteBuffer value; // required
    /**
     * the TDelete to execute if the check succeeds
     */
    public TDelete deleteSingle; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * to check in and delete from
       */
      TABLE((short)1, "table"),
      /**
       * row to check
       */
      ROW((short)2, "row"),
      /**
       * column family to check
       */
      FAMILY((short)3, "family"),
      /**
       * column qualifier to check
       */
      QUALIFIER((short)4, "qualifier"),
      /**
       * the expected value, if not provided the
       * check is for the non-existence of the
       * column in question
       */
      VALUE((short)5, "value"),
      /**
       * the TDelete to execute if the check succeeds
       */
      DELETE_SINGLE((short)6, "deleteSingle");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // ROW
            return ROW;
          case 3: // FAMILY
            return FAMILY;
          case 4: // QUALIFIER
            return QUALIFIER;
          case 5: // VALUE
            return VALUE;
          case 6: // DELETE_SINGLE
            return DELETE_SINGLE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.FAMILY, new org.apache.thrift.meta_data.FieldMetaData("family", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.QUALIFIER, new org.apache.thrift.meta_data.FieldMetaData("qualifier", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.DELETE_SINGLE, new org.apache.thrift.meta_data.FieldMetaData("deleteSingle", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TDelete.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkAndDelete_args.class, metaDataMap);
    }

    public checkAndDelete_args() {
    }

    public checkAndDelete_args(
      ByteBuffer table,
      ByteBuffer row,
      ByteBuffer family,
      ByteBuffer qualifier,
      ByteBuffer value,
      TDelete deleteSingle)
    {
      this();
      this.table = table;
      this.row = row;
      this.family = family;
      this.qualifier = qualifier;
      this.value = value;
      this.deleteSingle = deleteSingle;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkAndDelete_args(checkAndDelete_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetRow()) {
        this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
;
      }
      if (other.isSetFamily()) {
        this.family = org.apache.thrift.TBaseHelper.copyBinary(other.family);
;
      }
      if (other.isSetQualifier()) {
        this.qualifier = org.apache.thrift.TBaseHelper.copyBinary(other.qualifier);
;
      }
      if (other.isSetValue()) {
        this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
;
      }
      if (other.isSetDeleteSingle()) {
        this.deleteSingle = new TDelete(other.deleteSingle);
      }
    }

    public checkAndDelete_args deepCopy() {
      return new checkAndDelete_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.row = null;
      this.family = null;
      this.qualifier = null;
      this.value = null;
      this.deleteSingle = null;
    }

    /**
     * to check in and delete from
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * to check in and delete from
     */
    public checkAndDelete_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public checkAndDelete_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * row to check
     */
    public byte[] getRow() {
      setRow(org.apache.thrift.TBaseHelper.rightSize(row));
      return row == null ? null : row.array();
    }

    public ByteBuffer bufferForRow() {
      return row;
    }

    /**
     * row to check
     */
    public checkAndDelete_args setRow(byte[] row) {
      setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row));
      return this;
    }

    public checkAndDelete_args setRow(ByteBuffer row) {
      this.row = row;
      return this;
    }

    public void unsetRow() {
      this.row = null;
    }

    /** Returns true if field row is set (has been assigned a value) and false otherwise */
    public boolean isSetRow() {
      return this.row != null;
    }

    public void setRowIsSet(boolean value) {
      if (!value) {
        this.row = null;
      }
    }

    /**
     * column family to check
     */
    public byte[] getFamily() {
      setFamily(org.apache.thrift.TBaseHelper.rightSize(family));
      return family == null ? null : family.array();
    }

    public ByteBuffer bufferForFamily() {
      return family;
    }

    /**
     * column family to check
     */
    public checkAndDelete_args setFamily(byte[] family) {
      setFamily(family == null ? (ByteBuffer)null : ByteBuffer.wrap(family));
      return this;
    }

    public checkAndDelete_args setFamily(ByteBuffer family) {
      this.family = family;
      return this;
    }

    public void unsetFamily() {
      this.family = null;
    }

    /** Returns true if field family is set (has been assigned a value) and false otherwise */
    public boolean isSetFamily() {
      return this.family != null;
    }

    public void setFamilyIsSet(boolean value) {
      if (!value) {
        this.family = null;
      }
    }

    /**
     * column qualifier to check
     */
    public byte[] getQualifier() {
      setQualifier(org.apache.thrift.TBaseHelper.rightSize(qualifier));
      return qualifier == null ? null : qualifier.array();
    }

    public ByteBuffer bufferForQualifier() {
      return qualifier;
    }

    /**
     * column qualifier to check
     */
    public checkAndDelete_args setQualifier(byte[] qualifier) {
      setQualifier(qualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(qualifier));
      return this;
    }

    public checkAndDelete_args setQualifier(ByteBuffer qualifier) {
      this.qualifier = qualifier;
      return this;
    }

    public void unsetQualifier() {
      this.qualifier = null;
    }

    /** Returns true if field qualifier is set (has been assigned a value) and false otherwise */
    public boolean isSetQualifier() {
      return this.qualifier != null;
    }

    public void setQualifierIsSet(boolean value) {
      if (!value) {
        this.qualifier = null;
      }
    }

    /**
     * the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     */
    public byte[] getValue() {
      setValue(org.apache.thrift.TBaseHelper.rightSize(value));
      return value == null ? null : value.array();
    }

    public ByteBuffer bufferForValue() {
      return value;
    }

    /**
     * the expected value, if not provided the
     * check is for the non-existence of the
     * column in question
     */
    public checkAndDelete_args setValue(byte[] value) {
      setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value));
      return this;
    }

    public checkAndDelete_args setValue(ByteBuffer value) {
      this.value = value;
      return this;
    }

    public void unsetValue() {
      this.value = null;
    }

    /** Returns true if field value is set (has been assigned a value) and false otherwise */
    public boolean isSetValue() {
      return this.value != null;
    }

    public void setValueIsSet(boolean value) {
      if (!value) {
        this.value = null;
      }
    }

    /**
     * the TDelete to execute if the check succeeds
     */
    public TDelete getDeleteSingle() {
      return this.deleteSingle;
    }

    /**
     * the TDelete to execute if the check succeeds
     */
    public checkAndDelete_args setDeleteSingle(TDelete deleteSingle) {
      this.deleteSingle = deleteSingle;
      return this;
    }

    public void unsetDeleteSingle() {
      this.deleteSingle = null;
    }

    /** Returns true if field deleteSingle is set (has been assigned a value) and false otherwise */
    public boolean isSetDeleteSingle() {
      return this.deleteSingle != null;
    }

    public void setDeleteSingleIsSet(boolean value) {
      if (!value) {
        this.deleteSingle = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case ROW:
        if (value == null) {
          unsetRow();
        } else {
          setRow((ByteBuffer)value);
        }
        break;

      case FAMILY:
        if (value == null) {
          unsetFamily();
        } else {
          setFamily((ByteBuffer)value);
        }
        break;

      case QUALIFIER:
        if (value == null) {
          unsetQualifier();
        } else {
          setQualifier((ByteBuffer)value);
        }
        break;

      case VALUE:
        if (value == null) {
          unsetValue();
        } else {
          setValue((ByteBuffer)value);
        }
        break;

      case DELETE_SINGLE:
        if (value == null) {
          unsetDeleteSingle();
        } else {
          setDeleteSingle((TDelete)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case ROW:
        return getRow();

      case FAMILY:
        return getFamily();

      case QUALIFIER:
        return getQualifier();

      case VALUE:
        return getValue();

      case DELETE_SINGLE:
        return getDeleteSingle();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case ROW:
        return isSetRow();
      case FAMILY:
        return isSetFamily();
      case QUALIFIER:
        return isSetQualifier();
      case VALUE:
        return isSetValue();
      case DELETE_SINGLE:
        return isSetDeleteSingle();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof checkAndDelete_args)
        return this.equals((checkAndDelete_args)that);
      return false;
    }

    public boolean equals(checkAndDelete_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_row = true && this.isSetRow();
      boolean that_present_row = true && that.isSetRow();
      if (this_present_row || that_present_row) {
        if (!(this_present_row && that_present_row))
          return false;
        if (!this.row.equals(that.row))
          return false;
      }

      boolean this_present_family = true && this.isSetFamily();
      boolean that_present_family = true && that.isSetFamily();
      if (this_present_family || that_present_family) {
        if (!(this_present_family && that_present_family))
          return false;
        if (!this.family.equals(that.family))
          return false;
      }

      boolean this_present_qualifier = true && this.isSetQualifier();
      boolean that_present_qualifier = true && that.isSetQualifier();
      if (this_present_qualifier || that_present_qualifier) {
        if (!(this_present_qualifier && that_present_qualifier))
          return false;
        if (!this.qualifier.equals(that.qualifier))
          return false;
      }

      boolean this_present_value = true && this.isSetValue();
      boolean that_present_value = true && that.isSetValue();
      if (this_present_value || that_present_value) {
        if (!(this_present_value && that_present_value))
          return false;
        if (!this.value.equals(that.value))
          return false;
      }

      boolean this_present_deleteSingle = true && this.isSetDeleteSingle();
      boolean that_present_deleteSingle = true && that.isSetDeleteSingle();
      if (this_present_deleteSingle || that_present_deleteSingle) {
        if (!(this_present_deleteSingle && that_present_deleteSingle))
          return false;
        if (!this.deleteSingle.equals(that.deleteSingle))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(checkAndDelete_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      checkAndDelete_args typedOther = (checkAndDelete_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetRow()).compareTo(typedOther.isSetRow());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRow()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.row, typedOther.row);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetFamily()).compareTo(typedOther.isSetFamily());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFamily()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.family, typedOther.family);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetQualifier()).compareTo(typedOther.isSetQualifier());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQualifier()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.qualifier, typedOther.qualifier);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetValue()).compareTo(typedOther.isSetValue());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValue()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, typedOther.value);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetDeleteSingle()).compareTo(typedOther.isSetDeleteSingle());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDeleteSingle()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.deleteSingle, typedOther.deleteSingle);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("checkAndDelete_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("row:");
      if (this.row == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.row, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("family:");
      if (this.family == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.family, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("qualifier:");
      if (this.qualifier == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.qualifier, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("value:");
      if (this.value == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.value, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("deleteSingle:");
      if (this.deleteSingle == null) {
        sb.append("null");
      } else {
        sb.append(this.deleteSingle);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (row == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'row' was not present! Struct: " + toString());
      }
      if (family == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'family' was not present! Struct: " + toString());
      }
      if (qualifier == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'qualifier' was not present! Struct: " + toString());
      }
      if (deleteSingle == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'deleteSingle' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkAndDelete_argsStandardSchemeFactory implements SchemeFactory {
      public checkAndDelete_argsStandardScheme getScheme() {
        return new checkAndDelete_argsStandardScheme();
      }
    }

    private static class checkAndDelete_argsStandardScheme extends StandardScheme<checkAndDelete_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, checkAndDelete_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ROW
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.row = iprot.readBinary();
                struct.setRowIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // FAMILY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.family = iprot.readBinary();
                struct.setFamilyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // QUALIFIER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.qualifier = iprot.readBinary();
                struct.setQualifierIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // VALUE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.value = iprot.readBinary();
                struct.setValueIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // DELETE_SINGLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.deleteSingle = new TDelete();
                struct.deleteSingle.read(iprot);
                struct.setDeleteSingleIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkAndDelete_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.row != null) {
          oprot.writeFieldBegin(ROW_FIELD_DESC);
          oprot.writeBinary(struct.row);
          oprot.writeFieldEnd();
        }
        if (struct.family != null) {
          oprot.writeFieldBegin(FAMILY_FIELD_DESC);
          oprot.writeBinary(struct.family);
          oprot.writeFieldEnd();
        }
        if (struct.qualifier != null) {
          oprot.writeFieldBegin(QUALIFIER_FIELD_DESC);
          oprot.writeBinary(struct.qualifier);
          oprot.writeFieldEnd();
        }
        if (struct.value != null) {
          oprot.writeFieldBegin(VALUE_FIELD_DESC);
          oprot.writeBinary(struct.value);
          oprot.writeFieldEnd();
        }
        if (struct.deleteSingle != null) {
          oprot.writeFieldBegin(DELETE_SINGLE_FIELD_DESC);
          struct.deleteSingle.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkAndDelete_argsTupleSchemeFactory implements SchemeFactory {
      public checkAndDelete_argsTupleScheme getScheme() {
        return new checkAndDelete_argsTupleScheme();
      }
    }

    private static class checkAndDelete_argsTupleScheme extends TupleScheme<checkAndDelete_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, checkAndDelete_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        oprot.writeBinary(struct.row);
        oprot.writeBinary(struct.family);
        oprot.writeBinary(struct.qualifier);
        struct.deleteSingle.write(oprot);
        BitSet optionals = new BitSet();
        if (struct.isSetValue()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetValue()) {
          oprot.writeBinary(struct.value);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkAndDelete_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.row = iprot.readBinary();
        struct.setRowIsSet(true);
        struct.family = iprot.readBinary();
        struct.setFamilyIsSet(true);
        struct.qualifier = iprot.readBinary();
        struct.setQualifierIsSet(true);
        struct.deleteSingle = new TDelete();
        struct.deleteSingle.read(iprot);
        struct.setDeleteSingleIsSet(true);
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.value = iprot.readBinary();
          struct.setValueIsSet(true);
        }
      }
    }

  }

  public static class checkAndDelete_result implements org.apache.thrift.TBase<checkAndDelete_result, checkAndDelete_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkAndDelete_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new checkAndDelete_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new checkAndDelete_resultTupleSchemeFactory());
    }

    public boolean success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private BitSet __isset_bit_vector = new BitSet(1);
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkAndDelete_result.class, metaDataMap);
    }

    public checkAndDelete_result() {
    }

    public checkAndDelete_result(
      boolean success,
      TIOError io)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public checkAndDelete_result(checkAndDelete_result other) {
      __isset_bit_vector.clear();
      __isset_bit_vector.or(other.__isset_bit_vector);
      this.success = other.success;
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public checkAndDelete_result deepCopy() {
      return new checkAndDelete_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.io = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public checkAndDelete_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
    }

    public TIOError getIo() {
      return this.io;
    }

    public checkAndDelete_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Boolean)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Boolean.valueOf(isSuccess());

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof checkAndDelete_result)
        return this.equals((checkAndDelete_result)that);
      return false;
    }

    public boolean equals(checkAndDelete_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(checkAndDelete_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      checkAndDelete_result typedOther = (checkAndDelete_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("checkAndDelete_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class checkAndDelete_resultStandardSchemeFactory implements SchemeFactory {
      public checkAndDelete_resultStandardScheme getScheme() {
        return new checkAndDelete_resultStandardScheme();
      }
    }

    private static class checkAndDelete_resultStandardScheme extends StandardScheme<checkAndDelete_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, checkAndDelete_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, checkAndDelete_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
        oprot.writeBool(struct.success);
        oprot.writeFieldEnd();
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class checkAndDelete_resultTupleSchemeFactory implements SchemeFactory {
      public checkAndDelete_resultTupleScheme getScheme() {
        return new checkAndDelete_resultTupleScheme();
      }
    }

    private static class checkAndDelete_resultTupleScheme extends TupleScheme<checkAndDelete_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, checkAndDelete_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, checkAndDelete_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class increment_args implements org.apache.thrift.TBase<increment_args, increment_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("increment_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField INCREMENT_FIELD_DESC = new org.apache.thrift.protocol.TField("increment", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new increment_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new increment_argsTupleSchemeFactory());
    }

    /**
     * the table to increment the value on
     */
    public ByteBuffer table; // required
    /**
     * the TIncrement to increment
     */
    public TIncrement increment; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to increment the value on
       */
      TABLE((short)1, "table"),
      /**
       * the TIncrement to increment
       */
      INCREMENT((short)2, "increment");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // INCREMENT
            return INCREMENT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.INCREMENT, new org.apache.thrift.meta_data.FieldMetaData("increment", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TIncrement.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(increment_args.class, metaDataMap);
    }

    public increment_args() {
    }

    public increment_args(
      ByteBuffer table,
      TIncrement increment)
    {
      this();
      this.table = table;
      this.increment = increment;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public increment_args(increment_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetIncrement()) {
        this.increment = new TIncrement(other.increment);
      }
    }

    public increment_args deepCopy() {
      return new increment_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.increment = null;
    }

    /**
     * the table to increment the value on
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to increment the value on
     */
    public increment_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public increment_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * the TIncrement to increment
     */
    public TIncrement getIncrement() {
      return this.increment;
    }

    /**
     * the TIncrement to increment
     */
    public increment_args setIncrement(TIncrement increment) {
      this.increment = increment;
      return this;
    }

    public void unsetIncrement() {
      this.increment = null;
    }

    /** Returns true if field increment is set (has been assigned a value) and false otherwise */
    public boolean isSetIncrement() {
      return this.increment != null;
    }

    public void setIncrementIsSet(boolean value) {
      if (!value) {
        this.increment = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case INCREMENT:
        if (value == null) {
          unsetIncrement();
        } else {
          setIncrement((TIncrement)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case INCREMENT:
        return getIncrement();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case INCREMENT:
        return isSetIncrement();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof increment_args)
        return this.equals((increment_args)that);
      return false;
    }

    public boolean equals(increment_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_increment = true && this.isSetIncrement();
      boolean that_present_increment = true && that.isSetIncrement();
      if (this_present_increment || that_present_increment) {
        if (!(this_present_increment && that_present_increment))
          return false;
        if (!this.increment.equals(that.increment))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(increment_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      increment_args typedOther = (increment_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIncrement()).compareTo(typedOther.isSetIncrement());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIncrement()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.increment, typedOther.increment);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("increment_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("increment:");
      if (this.increment == null) {
        sb.append("null");
      } else {
        sb.append(this.increment);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (increment == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'increment' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class increment_argsStandardSchemeFactory implements SchemeFactory {
      public increment_argsStandardScheme getScheme() {
        return new increment_argsStandardScheme();
      }
    }

    private static class increment_argsStandardScheme extends StandardScheme<increment_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, increment_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // INCREMENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.increment = new TIncrement();
                struct.increment.read(iprot);
                struct.setIncrementIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, increment_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.increment != null) {
          oprot.writeFieldBegin(INCREMENT_FIELD_DESC);
          struct.increment.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class increment_argsTupleSchemeFactory implements SchemeFactory {
      public increment_argsTupleScheme getScheme() {
        return new increment_argsTupleScheme();
      }
    }

    private static class increment_argsTupleScheme extends TupleScheme<increment_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, increment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        struct.increment.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, increment_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.increment = new TIncrement();
        struct.increment.read(iprot);
        struct.setIncrementIsSet(true);
      }
    }

  }

  public static class increment_result implements org.apache.thrift.TBase<increment_result, increment_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("increment_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new increment_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new increment_resultTupleSchemeFactory());
    }

    public TResult success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TResult.class)));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(increment_result.class, metaDataMap);
    }

    public increment_result() {
    }

    public increment_result(
      TResult success,
      TIOError io)
    {
      this();
      this.success = success;
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public increment_result(increment_result other) {
      if (other.isSetSuccess()) {
        this.success = new TResult(other.success);
      }
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public increment_result deepCopy() {
      return new increment_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.io = null;
    }

    public TResult getSuccess() {
      return this.success;
    }

    public increment_result setSuccess(TResult success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public TIOError getIo() {
      return this.io;
    }

    public increment_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((TResult)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof increment_result)
        return this.equals((increment_result)that);
      return false;
    }

    public boolean equals(increment_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(increment_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      increment_result typedOther = (increment_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("increment_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class increment_resultStandardSchemeFactory implements SchemeFactory {
      public increment_resultStandardScheme getScheme() {
        return new increment_resultStandardScheme();
      }
    }

    private static class increment_resultStandardScheme extends StandardScheme<increment_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, increment_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new TResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, increment_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class increment_resultTupleSchemeFactory implements SchemeFactory {
      public increment_resultTupleScheme getScheme() {
        return new increment_resultTupleScheme();
      }
    }

    private static class increment_resultTupleScheme extends TupleScheme<increment_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, increment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, increment_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new TResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class openScanner_args implements org.apache.thrift.TBase<openScanner_args, openScanner_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("openScanner_args");

    private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField SCAN_FIELD_DESC = new org.apache.thrift.protocol.TField("scan", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new openScanner_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new openScanner_argsTupleSchemeFactory());
    }

    /**
     * the table to get the Scanner for
     */
    public ByteBuffer table; // required
    /**
     * the scan object to get a Scanner for
     */
    public TScan scan; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the table to get the Scanner for
       */
      TABLE((short)1, "table"),
      /**
       * the scan object to get a Scanner for
       */
      SCAN((short)2, "scan");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // TABLE
            return TABLE;
          case 2: // SCAN
            return SCAN;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.SCAN, new org.apache.thrift.meta_data.FieldMetaData("scan", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TScan.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(openScanner_args.class, metaDataMap);
    }

    public openScanner_args() {
    }

    public openScanner_args(
      ByteBuffer table,
      TScan scan)
    {
      this();
      this.table = table;
      this.scan = scan;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public openScanner_args(openScanner_args other) {
      if (other.isSetTable()) {
        this.table = org.apache.thrift.TBaseHelper.copyBinary(other.table);
;
      }
      if (other.isSetScan()) {
        this.scan = new TScan(other.scan);
      }
    }

    public openScanner_args deepCopy() {
      return new openScanner_args(this);
    }

    @Override
    public void clear() {
      this.table = null;
      this.scan = null;
    }

    /**
     * the table to get the Scanner for
     */
    public byte[] getTable() {
      setTable(org.apache.thrift.TBaseHelper.rightSize(table));
      return table == null ? null : table.array();
    }

    public ByteBuffer bufferForTable() {
      return table;
    }

    /**
     * the table to get the Scanner for
     */
    public openScanner_args setTable(byte[] table) {
      setTable(table == null ? (ByteBuffer)null : ByteBuffer.wrap(table));
      return this;
    }

    public openScanner_args setTable(ByteBuffer table) {
      this.table = table;
      return this;
    }

    public void unsetTable() {
      this.table = null;
    }

    /** Returns true if field table is set (has been assigned a value) and false otherwise */
    public boolean isSetTable() {
      return this.table != null;
    }

    public void setTableIsSet(boolean value) {
      if (!value) {
        this.table = null;
      }
    }

    /**
     * the scan object to get a Scanner for
     */
    public TScan getScan() {
      return this.scan;
    }

    /**
     * the scan object to get a Scanner for
     */
    public openScanner_args setScan(TScan scan) {
      this.scan = scan;
      return this;
    }

    public void unsetScan() {
      this.scan = null;
    }

    /** Returns true if field scan is set (has been assigned a value) and false otherwise */
    public boolean isSetScan() {
      return this.scan != null;
    }

    public void setScanIsSet(boolean value) {
      if (!value) {
        this.scan = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case TABLE:
        if (value == null) {
          unsetTable();
        } else {
          setTable((ByteBuffer)value);
        }
        break;

      case SCAN:
        if (value == null) {
          unsetScan();
        } else {
          setScan((TScan)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case TABLE:
        return getTable();

      case SCAN:
        return getScan();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case TABLE:
        return isSetTable();
      case SCAN:
        return isSetScan();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof openScanner_args)
        return this.equals((openScanner_args)that);
      return false;
    }

    public boolean equals(openScanner_args that) {
      if (that == null)
        return false;

      boolean this_present_table = true && this.isSetTable();
      boolean that_present_table = true && that.isSetTable();
      if (this_present_table || that_present_table) {
        if (!(this_present_table && that_present_table))
          return false;
        if (!this.table.equals(that.table))
          return false;
      }

      boolean this_present_scan = true && this.isSetScan();
      boolean that_present_scan = true && that.isSetScan();
      if (this_present_scan || that_present_scan) {
        if (!(this_present_scan && that_present_scan))
          return false;
        if (!this.scan.equals(that.scan))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(openScanner_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      openScanner_args typedOther = (openScanner_args)other;

      lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTable()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetScan()).compareTo(typedOther.isSetScan());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScan()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scan, typedOther.scan);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("openScanner_args(");
      boolean first = true;

      sb.append("table:");
      if (this.table == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.table, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("scan:");
      if (this.scan == null) {
        sb.append("null");
      } else {
        sb.append(this.scan);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (table == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'table' was not present! Struct: " + toString());
      }
      if (scan == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'scan' was not present! Struct: " + toString());
      }
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class openScanner_argsStandardSchemeFactory implements SchemeFactory {
      public openScanner_argsStandardScheme getScheme() {
        return new openScanner_argsStandardScheme();
      }
    }

    private static class openScanner_argsStandardScheme extends StandardScheme<openScanner_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, openScanner_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // TABLE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.table = iprot.readBinary();
                struct.setTableIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SCAN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.scan = new TScan();
                struct.scan.read(iprot);
                struct.setScanIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, openScanner_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.table != null) {
          oprot.writeFieldBegin(TABLE_FIELD_DESC);
          oprot.writeBinary(struct.table);
          oprot.writeFieldEnd();
        }
        if (struct.scan != null) {
          oprot.writeFieldBegin(SCAN_FIELD_DESC);
          struct.scan.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class openScanner_argsTupleSchemeFactory implements SchemeFactory {
      public openScanner_argsTupleScheme getScheme() {
        return new openScanner_argsTupleScheme();
      }
    }

    private static class openScanner_argsTupleScheme extends TupleScheme<openScanner_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, openScanner_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.table);
        struct.scan.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, openScanner_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.table = iprot.readBinary();
        struct.setTableIsSet(true);
        struct.scan = new TScan();
        struct.scan.read(iprot);
        struct.setScanIsSet(true);
      }
    }

  }

  public static class openScanner_result implements org.apache.thrift.TBase<openScanner_result, openScanner_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("openScanner_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new openScanner_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new openScanner_resultTupleSchemeFactory());
    }

    public int success; // required
    public TIOError io; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private BitSet __isset_bit_vector = new BitSet(1);
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(openScanner_result.class, metaDataMap);
    }

    public openScanner_result() {
    }

    public openScanner_result(
      int success,
      TIOError io)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.io = io;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public openScanner_result(openScanner_result other) {
      __isset_bit_vector.clear();
      __isset_bit_vector.or(other.__isset_bit_vector);
      this.success = other.success;
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
    }

    public openScanner_result deepCopy() {
      return new openScanner_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = 0;
      this.io = null;
    }

    public int getSuccess() {
      return this.success;
    }

    public openScanner_result setSuccess(int success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
    }

    public TIOError getIo() {
      return this.io;
    }

    public openScanner_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((Integer)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return Integer.valueOf(getSuccess());

      case IO:
        return getIo();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof openScanner_result)
        return this.equals((openScanner_result)that);
      return false;
    }

    public boolean equals(openScanner_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(openScanner_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      openScanner_result typedOther = (openScanner_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("openScanner_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class openScanner_resultStandardSchemeFactory implements SchemeFactory {
      public openScanner_resultStandardScheme getScheme() {
        return new openScanner_resultStandardScheme();
      }
    }

    private static class openScanner_resultStandardScheme extends StandardScheme<openScanner_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, openScanner_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.success = iprot.readI32();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, openScanner_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
        oprot.writeI32(struct.success);
        oprot.writeFieldEnd();
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class openScanner_resultTupleSchemeFactory implements SchemeFactory {
      public openScanner_resultTupleScheme getScheme() {
        return new openScanner_resultTupleScheme();
      }
    }

    private static class openScanner_resultTupleScheme extends TupleScheme<openScanner_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, openScanner_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeI32(struct.success);
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, openScanner_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readI32();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
      }
    }

  }

  public static class getScannerRows_args implements org.apache.thrift.TBase<getScannerRows_args, getScannerRows_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getScannerRows_args");

    private static final org.apache.thrift.protocol.TField SCANNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("scannerId", org.apache.thrift.protocol.TType.I32, (short)1);
    private static final org.apache.thrift.protocol.TField NUM_ROWS_FIELD_DESC = new org.apache.thrift.protocol.TField("numRows", org.apache.thrift.protocol.TType.I32, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getScannerRows_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getScannerRows_argsTupleSchemeFactory());
    }

    /**
     * the Id of the Scanner to return rows from. This is an Id returned from the openScanner function.
     */
    public int scannerId; // required
    /**
     * number of rows to return
     */
    public int numRows; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the Id of the Scanner to return rows from. This is an Id returned from the openScanner function.
       */
      SCANNER_ID((short)1, "scannerId"),
      /**
       * number of rows to return
       */
      NUM_ROWS((short)2, "numRows");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // SCANNER_ID
            return SCANNER_ID;
          case 2: // NUM_ROWS
            return NUM_ROWS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SCANNERID_ISSET_ID = 0;
    private static final int __NUMROWS_ISSET_ID = 1;
    private BitSet __isset_bit_vector = new BitSet(2);
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SCANNER_ID, new org.apache.thrift.meta_data.FieldMetaData("scannerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.NUM_ROWS, new org.apache.thrift.meta_data.FieldMetaData("numRows", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getScannerRows_args.class, metaDataMap);
    }

    public getScannerRows_args() {
      this.numRows = 1;

    }

    public getScannerRows_args(
      int scannerId,
      int numRows)
    {
      this();
      this.scannerId = scannerId;
      setScannerIdIsSet(true);
      this.numRows = numRows;
      setNumRowsIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getScannerRows_args(getScannerRows_args other) {
      __isset_bit_vector.clear();
      __isset_bit_vector.or(other.__isset_bit_vector);
      this.scannerId = other.scannerId;
      this.numRows = other.numRows;
    }

    public getScannerRows_args deepCopy() {
      return new getScannerRows_args(this);
    }

    @Override
    public void clear() {
      setScannerIdIsSet(false);
      this.scannerId = 0;
      this.numRows = 1;

    }

    /**
     * the Id of the Scanner to return rows from. This is an Id returned from the openScanner function.
     */
    public int getScannerId() {
      return this.scannerId;
    }

    /**
     * the Id of the Scanner to return rows from. This is an Id returned from the openScanner function.
     */
    public getScannerRows_args setScannerId(int scannerId) {
      this.scannerId = scannerId;
      setScannerIdIsSet(true);
      return this;
    }

    public void unsetScannerId() {
      __isset_bit_vector.clear(__SCANNERID_ISSET_ID);
    }

    /** Returns true if field scannerId is set (has been assigned a value) and false otherwise */
    public boolean isSetScannerId() {
      return __isset_bit_vector.get(__SCANNERID_ISSET_ID);
    }

    public void setScannerIdIsSet(boolean value) {
      __isset_bit_vector.set(__SCANNERID_ISSET_ID, value);
    }

    /**
     * number of rows to return
     */
    public int getNumRows() {
      return this.numRows;
    }

    /**
     * number of rows to return
     */
    public getScannerRows_args setNumRows(int numRows) {
      this.numRows = numRows;
      setNumRowsIsSet(true);
      return this;
    }

    public void unsetNumRows() {
      __isset_bit_vector.clear(__NUMROWS_ISSET_ID);
    }

    /** Returns true if field numRows is set (has been assigned a value) and false otherwise */
    public boolean isSetNumRows() {
      return __isset_bit_vector.get(__NUMROWS_ISSET_ID);
    }

    public void setNumRowsIsSet(boolean value) {
      __isset_bit_vector.set(__NUMROWS_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SCANNER_ID:
        if (value == null) {
          unsetScannerId();
        } else {
          setScannerId((Integer)value);
        }
        break;

      case NUM_ROWS:
        if (value == null) {
          unsetNumRows();
        } else {
          setNumRows((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SCANNER_ID:
        return Integer.valueOf(getScannerId());

      case NUM_ROWS:
        return Integer.valueOf(getNumRows());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SCANNER_ID:
        return isSetScannerId();
      case NUM_ROWS:
        return isSetNumRows();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getScannerRows_args)
        return this.equals((getScannerRows_args)that);
      return false;
    }

    public boolean equals(getScannerRows_args that) {
      if (that == null)
        return false;

      boolean this_present_scannerId = true;
      boolean that_present_scannerId = true;
      if (this_present_scannerId || that_present_scannerId) {
        if (!(this_present_scannerId && that_present_scannerId))
          return false;
        if (this.scannerId != that.scannerId)
          return false;
      }

      boolean this_present_numRows = true;
      boolean that_present_numRows = true;
      if (this_present_numRows || that_present_numRows) {
        if (!(this_present_numRows && that_present_numRows))
          return false;
        if (this.numRows != that.numRows)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(getScannerRows_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      getScannerRows_args typedOther = (getScannerRows_args)other;

      lastComparison = Boolean.valueOf(isSetScannerId()).compareTo(typedOther.isSetScannerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScannerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scannerId, typedOther.scannerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetNumRows()).compareTo(typedOther.isSetNumRows());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNumRows()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.numRows, typedOther.numRows);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getScannerRows_args(");
      boolean first = true;

      sb.append("scannerId:");
      sb.append(this.scannerId);
      first = false;
      if (!first) sb.append(", ");
      sb.append("numRows:");
      sb.append(this.numRows);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // alas, we cannot check 'scannerId' because it's a primitive and you chose the non-beans generator.
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bit_vector = new BitSet(1);
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getScannerRows_argsStandardSchemeFactory implements SchemeFactory {
      public getScannerRows_argsStandardScheme getScheme() {
        return new getScannerRows_argsStandardScheme();
      }
    }

    private static class getScannerRows_argsStandardScheme extends StandardScheme<getScannerRows_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getScannerRows_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // SCANNER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.scannerId = iprot.readI32();
                struct.setScannerIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NUM_ROWS
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.numRows = iprot.readI32();
                struct.setNumRowsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetScannerId()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'scannerId' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getScannerRows_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(SCANNER_ID_FIELD_DESC);
        oprot.writeI32(struct.scannerId);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(NUM_ROWS_FIELD_DESC);
        oprot.writeI32(struct.numRows);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getScannerRows_argsTupleSchemeFactory implements SchemeFactory {
      public getScannerRows_argsTupleScheme getScheme() {
        return new getScannerRows_argsTupleScheme();
      }
    }

    private static class getScannerRows_argsTupleScheme extends TupleScheme<getScannerRows_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getScannerRows_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeI32(struct.scannerId);
        BitSet optionals = new BitSet();
        if (struct.isSetNumRows()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetNumRows()) {
          oprot.writeI32(struct.numRows);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getScannerRows_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.scannerId = iprot.readI32();
        struct.setScannerIdIsSet(true);
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.numRows = iprot.readI32();
          struct.setNumRowsIsSet(true);
        }
      }
    }

  }

  public static class getScannerRows_result implements org.apache.thrift.TBase<getScannerRows_result, getScannerRows_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getScannerRows_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField IA_FIELD_DESC = new org.apache.thrift.protocol.TField("ia", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new getScannerRows_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new getScannerRows_resultTupleSchemeFactory());
    }

    public List<TResult> success; // required
    public TIOError io; // required
    /**
     * if the scannerId is invalid
     */
    public TIllegalArgument ia; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      IO((short)1, "io"),
      /**
       * if the scannerId is invalid
       */
      IA((short)2, "ia");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // IO
            return IO;
          case 2: // IA
            return IA;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TResult.class))));
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.IA, new org.apache.thrift.meta_data.FieldMetaData("ia", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getScannerRows_result.class, metaDataMap);
    }

    public getScannerRows_result() {
    }

    public getScannerRows_result(
      List<TResult> success,
      TIOError io,
      TIllegalArgument ia)
    {
      this();
      this.success = success;
      this.io = io;
      this.ia = ia;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getScannerRows_result(getScannerRows_result other) {
      if (other.isSetSuccess()) {
        List<TResult> __this__success = new ArrayList<TResult>();
        for (TResult other_element : other.success) {
          __this__success.add(new TResult(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
      if (other.isSetIa()) {
        this.ia = new TIllegalArgument(other.ia);
      }
    }

    public getScannerRows_result deepCopy() {
      return new getScannerRows_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.io = null;
      this.ia = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<TResult> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(TResult elem) {
      if (this.success == null) {
        this.success = new ArrayList<TResult>();
      }
      this.success.add(elem);
    }

    public List<TResult> getSuccess() {
      return this.success;
    }

    public getScannerRows_result setSuccess(List<TResult> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public TIOError getIo() {
      return this.io;
    }

    public getScannerRows_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    /**
     * if the scannerId is invalid
     */
    public TIllegalArgument getIa() {
      return this.ia;
    }

    /**
     * if the scannerId is invalid
     */
    public getScannerRows_result setIa(TIllegalArgument ia) {
      this.ia = ia;
      return this;
    }

    public void unsetIa() {
      this.ia = null;
    }

    /** Returns true if field ia is set (has been assigned a value) and false otherwise */
    public boolean isSetIa() {
      return this.ia != null;
    }

    public void setIaIsSet(boolean value) {
      if (!value) {
        this.ia = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<TResult>)value);
        }
        break;

      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      case IA:
        if (value == null) {
          unsetIa();
        } else {
          setIa((TIllegalArgument)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IO:
        return getIo();

      case IA:
        return getIa();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case IO:
        return isSetIo();
      case IA:
        return isSetIa();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof getScannerRows_result)
        return this.equals((getScannerRows_result)that);
      return false;
    }

    public boolean equals(getScannerRows_result that) {
      if (that == null)
        return false;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      boolean this_present_ia = true && this.isSetIa();
      boolean that_present_ia = true && that.isSetIa();
      if (this_present_ia || that_present_ia) {
        if (!(this_present_ia && that_present_ia))
          return false;
        if (!this.ia.equals(that.ia))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(getScannerRows_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      getScannerRows_result typedOther = (getScannerRows_result)other;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIa()).compareTo(typedOther.isSetIa());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIa()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ia, typedOther.ia);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("getScannerRows_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ia:");
      if (this.ia == null) {
        sb.append("null");
      } else {
        sb.append(this.ia);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getScannerRows_resultStandardSchemeFactory implements SchemeFactory {
      public getScannerRows_resultStandardScheme getScheme() {
        return new getScannerRows_resultStandardScheme();
      }
    }

    private static class getScannerRows_resultStandardScheme extends StandardScheme<getScannerRows_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getScannerRows_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list88 = iprot.readListBegin();
                  struct.success = new ArrayList<TResult>(_list88.size);
                  for (int _i89 = 0; _i89 < _list88.size; ++_i89)
                  {
                    TResult _elem90; // optional
                    _elem90 = new TResult();
                    _elem90.read(iprot);
                    struct.success.add(_elem90);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // IA
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ia = new TIllegalArgument();
                struct.ia.read(iprot);
                struct.setIaIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getScannerRows_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (TResult _iter91 : struct.success)
            {
              _iter91.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ia != null) {
          oprot.writeFieldBegin(IA_FIELD_DESC);
          struct.ia.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getScannerRows_resultTupleSchemeFactory implements SchemeFactory {
      public getScannerRows_resultTupleScheme getScheme() {
        return new getScannerRows_resultTupleScheme();
      }
    }

    private static class getScannerRows_resultTupleScheme extends TupleScheme<getScannerRows_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getScannerRows_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIo()) {
          optionals.set(1);
        }
        if (struct.isSetIa()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (TResult _iter92 : struct.success)
            {
              _iter92.write(oprot);
            }
          }
        }
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
        if (struct.isSetIa()) {
          struct.ia.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getScannerRows_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list93 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<TResult>(_list93.size);
            for (int _i94 = 0; _i94 < _list93.size; ++_i94)
            {
              TResult _elem95; // optional
              _elem95 = new TResult();
              _elem95.read(iprot);
              struct.success.add(_elem95);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ia = new TIllegalArgument();
          struct.ia.read(iprot);
          struct.setIaIsSet(true);
        }
      }
    }

  }

  public static class closeScanner_args implements org.apache.thrift.TBase<closeScanner_args, closeScanner_args._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeScanner_args");

    private static final org.apache.thrift.protocol.TField SCANNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("scannerId", org.apache.thrift.protocol.TType.I32, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new closeScanner_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new closeScanner_argsTupleSchemeFactory());
    }

    /**
     * the Id of the Scanner to close *
     */
    public int scannerId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      /**
       * the Id of the Scanner to close *
       */
      SCANNER_ID((short)1, "scannerId");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // SCANNER_ID
            return SCANNER_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SCANNERID_ISSET_ID = 0;
    private BitSet __isset_bit_vector = new BitSet(1);
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SCANNER_ID, new org.apache.thrift.meta_data.FieldMetaData("scannerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeScanner_args.class, metaDataMap);
    }

    public closeScanner_args() {
    }

    public closeScanner_args(
      int scannerId)
    {
      this();
      this.scannerId = scannerId;
      setScannerIdIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeScanner_args(closeScanner_args other) {
      __isset_bit_vector.clear();
      __isset_bit_vector.or(other.__isset_bit_vector);
      this.scannerId = other.scannerId;
    }

    public closeScanner_args deepCopy() {
      return new closeScanner_args(this);
    }

    @Override
    public void clear() {
      setScannerIdIsSet(false);
      this.scannerId = 0;
    }

    /**
     * the Id of the Scanner to close *
     */
    public int getScannerId() {
      return this.scannerId;
    }

    /**
     * the Id of the Scanner to close *
     */
    public closeScanner_args setScannerId(int scannerId) {
      this.scannerId = scannerId;
      setScannerIdIsSet(true);
      return this;
    }

    public void unsetScannerId() {
      __isset_bit_vector.clear(__SCANNERID_ISSET_ID);
    }

    /** Returns true if field scannerId is set (has been assigned a value) and false otherwise */
    public boolean isSetScannerId() {
      return __isset_bit_vector.get(__SCANNERID_ISSET_ID);
    }

    public void setScannerIdIsSet(boolean value) {
      __isset_bit_vector.set(__SCANNERID_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SCANNER_ID:
        if (value == null) {
          unsetScannerId();
        } else {
          setScannerId((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SCANNER_ID:
        return Integer.valueOf(getScannerId());

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case SCANNER_ID:
        return isSetScannerId();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof closeScanner_args)
        return this.equals((closeScanner_args)that);
      return false;
    }

    public boolean equals(closeScanner_args that) {
      if (that == null)
        return false;

      boolean this_present_scannerId = true;
      boolean that_present_scannerId = true;
      if (this_present_scannerId || that_present_scannerId) {
        if (!(this_present_scannerId && that_present_scannerId))
          return false;
        if (this.scannerId != that.scannerId)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(closeScanner_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      closeScanner_args typedOther = (closeScanner_args)other;

      lastComparison = Boolean.valueOf(isSetScannerId()).compareTo(typedOther.isSetScannerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetScannerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scannerId, typedOther.scannerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("closeScanner_args(");
      boolean first = true;

      sb.append("scannerId:");
      sb.append(this.scannerId);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // alas, we cannot check 'scannerId' because it's a primitive and you chose the non-beans generator.
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bit_vector = new BitSet(1);
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeScanner_argsStandardSchemeFactory implements SchemeFactory {
      public closeScanner_argsStandardScheme getScheme() {
        return new closeScanner_argsStandardScheme();
      }
    }

    private static class closeScanner_argsStandardScheme extends StandardScheme<closeScanner_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, closeScanner_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // SCANNER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.scannerId = iprot.readI32();
                struct.setScannerIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetScannerId()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'scannerId' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeScanner_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(SCANNER_ID_FIELD_DESC);
        oprot.writeI32(struct.scannerId);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class closeScanner_argsTupleSchemeFactory implements SchemeFactory {
      public closeScanner_argsTupleScheme getScheme() {
        return new closeScanner_argsTupleScheme();
      }
    }

    private static class closeScanner_argsTupleScheme extends TupleScheme<closeScanner_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, closeScanner_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeI32(struct.scannerId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeScanner_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.scannerId = iprot.readI32();
        struct.setScannerIdIsSet(true);
      }
    }

  }

  public static class closeScanner_result implements org.apache.thrift.TBase<closeScanner_result, closeScanner_result._Fields>, java.io.Serializable, Cloneable   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeScanner_result");

    private static final org.apache.thrift.protocol.TField IO_FIELD_DESC = new org.apache.thrift.protocol.TField("io", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField IA_FIELD_DESC = new org.apache.thrift.protocol.TField("ia", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new closeScanner_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new closeScanner_resultTupleSchemeFactory());
    }

    public TIOError io; // required
    /**
     * if the scannerId is invalid
     */
    public TIllegalArgument ia; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      IO((short)1, "io"),
      /**
       * if the scannerId is invalid
       */
      IA((short)2, "ia");

      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

      static {
        for (_Fields field : EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // IO
            return IO;
          case 2: // IA
            return IA;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final String _fieldName;

      _Fields(short thriftId, String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.IO, new org.apache.thrift.meta_data.FieldMetaData("io", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.IA, new org.apache.thrift.meta_data.FieldMetaData("ia", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeScanner_result.class, metaDataMap);
    }

    public closeScanner_result() {
    }

    public closeScanner_result(
      TIOError io,
      TIllegalArgument ia)
    {
      this();
      this.io = io;
      this.ia = ia;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public closeScanner_result(closeScanner_result other) {
      if (other.isSetIo()) {
        this.io = new TIOError(other.io);
      }
      if (other.isSetIa()) {
        this.ia = new TIllegalArgument(other.ia);
      }
    }

    public closeScanner_result deepCopy() {
      return new closeScanner_result(this);
    }

    @Override
    public void clear() {
      this.io = null;
      this.ia = null;
    }

    public TIOError getIo() {
      return this.io;
    }

    public closeScanner_result setIo(TIOError io) {
      this.io = io;
      return this;
    }

    public void unsetIo() {
      this.io = null;
    }

    /** Returns true if field io is set (has been assigned a value) and false otherwise */
    public boolean isSetIo() {
      return this.io != null;
    }

    public void setIoIsSet(boolean value) {
      if (!value) {
        this.io = null;
      }
    }

    /**
     * if the scannerId is invalid
     */
    public TIllegalArgument getIa() {
      return this.ia;
    }

    /**
     * if the scannerId is invalid
     */
    public closeScanner_result setIa(TIllegalArgument ia) {
      this.ia = ia;
      return this;
    }

    public void unsetIa() {
      this.ia = null;
    }

    /** Returns true if field ia is set (has been assigned a value) and false otherwise */
    public boolean isSetIa() {
      return this.ia != null;
    }

    public void setIaIsSet(boolean value) {
      if (!value) {
        this.ia = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IO:
        if (value == null) {
          unsetIo();
        } else {
          setIo((TIOError)value);
        }
        break;

      case IA:
        if (value == null) {
          unsetIa();
        } else {
          setIa((TIllegalArgument)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IO:
        return getIo();

      case IA:
        return getIa();

      }
      throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new IllegalArgumentException();
      }

      switch (field) {
      case IO:
        return isSetIo();
      case IA:
        return isSetIa();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof closeScanner_result)
        return this.equals((closeScanner_result)that);
      return false;
    }

    public boolean equals(closeScanner_result that) {
      if (that == null)
        return false;

      boolean this_present_io = true && this.isSetIo();
      boolean that_present_io = true && that.isSetIo();
      if (this_present_io || that_present_io) {
        if (!(this_present_io && that_present_io))
          return false;
        if (!this.io.equals(that.io))
          return false;
      }

      boolean this_present_ia = true && this.isSetIa();
      boolean that_present_ia = true && that.isSetIa();
      if (this_present_ia || that_present_ia) {
        if (!(this_present_ia && that_present_ia))
          return false;
        if (!this.ia.equals(that.ia))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      return 0;
    }

    public int compareTo(closeScanner_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;
      closeScanner_result typedOther = (closeScanner_result)other;

      lastComparison = Boolean.valueOf(isSetIo()).compareTo(typedOther.isSetIo());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIo()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.io, typedOther.io);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIa()).compareTo(typedOther.isSetIa());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIa()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ia, typedOther.ia);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
      }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder("closeScanner_result(");
      boolean first = true;

      sb.append("io:");
      if (this.io == null) {
        sb.append("null");
      } else {
        sb.append(this.io);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ia:");
      if (this.ia == null) {
        sb.append("null");
      } else {
        sb.append(this.ia);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
      try {
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class closeScanner_resultStandardSchemeFactory implements SchemeFactory {
      public closeScanner_resultStandardScheme getScheme() {
        return new closeScanner_resultStandardScheme();
      }
    }

    private static class closeScanner_resultStandardScheme extends StandardScheme<closeScanner_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, closeScanner_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // IO
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.io = new TIOError();
                struct.io.read(iprot);
                struct.setIoIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // IA
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ia = new TIllegalArgument();
                struct.ia.read(iprot);
                struct.setIaIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, closeScanner_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.io != null) {
          oprot.writeFieldBegin(IO_FIELD_DESC);
          struct.io.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ia != null) {
          oprot.writeFieldBegin(IA_FIELD_DESC);
          struct.ia.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class closeScanner_resultTupleSchemeFactory implements SchemeFactory {
      public closeScanner_resultTupleScheme getScheme() {
        return new closeScanner_resultTupleScheme();
      }
    }

    private static class closeScanner_resultTupleScheme extends TupleScheme<closeScanner_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, closeScanner_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIo()) {
          optionals.set(0);
        }
        if (struct.isSetIa()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetIo()) {
          struct.io.write(oprot);
        }
        if (struct.isSetIa()) {
          struct.ia.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, closeScanner_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.io = new TIOError();
          struct.io.read(iprot);
          struct.setIoIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ia = new TIllegalArgument();
          struct.ia.read(iprot);
          struct.setIaIsSet(true);
        }
      }
    }

  }

}
