/**
 * Autogenerated by Thrift Compiler (0.9.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.cassandra.thrift;
/*
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 */


import org.apache.commons.lang3.builder.HashCodeBuilder;
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 org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
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 Cassandra {

  public interface Iface {

    public void login(AuthenticationRequest auth_request) throws AuthenticationException, AuthorizationException, org.apache.thrift.TException;

    public void set_keyspace(String keyspace) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is
     * the only method that can throw an exception under non-failure conditions.)
     * 
     * @param key
     * @param column_path
     * @param consistency_level
     */
    public ColumnOrSuperColumn get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name
     * pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned.
     * 
     * @param key
     * @param column_parent
     * @param predicate
     * @param consistency_level
     */
    public List<ColumnOrSuperColumn> get_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * returns the number of columns matching <code>predicate</code> for a particular <code>key</code>,
     * <code>ColumnFamily</code> and optionally <code>SuperColumn</code>.
     * 
     * @param key
     * @param column_parent
     * @param predicate
     * @param consistency_level
     */
    public int get_count(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Performs a get_slice for column_parent and predicate for the given keys in parallel.
     * 
     * @param keys
     * @param column_parent
     * @param predicate
     * @param consistency_level
     */
    public Map<ByteBuffer,List<ColumnOrSuperColumn>> multiget_slice(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Perform a get_count in parallel on the given list<binary> keys. The return value maps keys to the count found.
     * 
     * @param keys
     * @param column_parent
     * @param predicate
     * @param consistency_level
     */
    public Map<ByteBuffer,Integer> multiget_count(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * returns a subset of columns for a contiguous range of keys.
     * 
     * @param column_parent
     * @param predicate
     * @param range
     * @param consistency_level
     */
    public List<KeySlice> get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * returns a range of columns, wrapping to the next rows if necessary to collect max_results.
     * 
     * @param column_family
     * @param range
     * @param start_column
     * @param consistency_level
     */
    public List<KeySlice> get_paged_slice(String column_family, KeyRange range, ByteBuffer start_column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Returns the subset of columns specified in SlicePredicate for the rows matching the IndexClause
     * @deprecated use get_range_slices instead with range.row_filter specified
     * 
     * @param column_parent
     * @param index_clause
     * @param column_predicate
     * @param consistency_level
     */
    public List<KeySlice> get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Insert a Column at the given column_parent.column_family and optional column_parent.super_column.
     * 
     * @param key
     * @param column_parent
     * @param column
     * @param consistency_level
     */
    public void insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Increment or decrement a counter.
     * 
     * @param key
     * @param column_parent
     * @param column
     * @param consistency_level
     */
    public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Atomic compare and set.
     * 
     * If the cas is successfull, the success boolean in CASResult will be true and there will be no current_values.
     * Otherwise, success will be false and current_values will contain the current values for the columns in
     * expected (that, by definition of compare-and-set, will differ from the values in expected).
     * 
     * A cas operation takes 2 consistency level. The first one, serial_consistency_level, simply indicates the
     * level of serialization required. This can be either ConsistencyLevel.SERIAL or ConsistencyLevel.LOCAL_SERIAL.
     * The second one, commit_consistency_level, defines the consistency level for the commit phase of the cas. This
     * is a more traditional consistency level (the same CL than for traditional writes are accepted) that impact
     * the visibility for reads of the operation. For instance, if commit_consistency_level is QUORUM, then it is
     * guaranteed that a followup QUORUM read will see the cas write (if that one was successful obviously). If
     * commit_consistency_level is ANY, you will need to use a SERIAL/LOCAL_SERIAL read to be guaranteed to see
     * the write.
     * 
     * @param key
     * @param column_family
     * @param expected
     * @param updates
     * @param serial_consistency_level
     * @param commit_consistency_level
     */
    public CASResult cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, ConsistencyLevel serial_consistency_level, ConsistencyLevel commit_consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
     * that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
     * row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.
     * 
     * @param key
     * @param column_path
     * @param timestamp
     * @param consistency_level
     */
    public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Remove a counter at the specified location.
     * Note that counters have limited support for deletes: if you remove a counter, you must wait to issue any following update
     * until the delete has reached all the nodes and all of them have been fully compacted.
     * 
     * @param key
     * @param path
     * @param consistency_level
     */
    public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     *   Mutate many columns or super columns for many row keys. See also: Mutation.
     * 
     *   mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
     * *
     * 
     * @param mutation_map
     * @param consistency_level
     */
    public void batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     *   Atomically mutate many columns or super columns for many row keys. See also: Mutation.
     * 
     *   mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
     * *
     * 
     * @param mutation_map
     * @param consistency_level
     */
    public void atomic_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Truncate will mark and entire column family as deleted.
     * From the user's perspective a successful call to truncate will result complete data deletion from cfname.
     * Internally, however, disk space will not be immediatily released, as with all deletes in cassandra, this one
     * only marks the data as deleted.
     * The operation succeeds only if all hosts in the cluster at available and will throw an UnavailableException if
     * some hosts are down.
     * 
     * @param cfname
     */
    public void truncate(String cfname) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * Select multiple slices of a key in a single RPC operation
     * 
     * @param request
     */
    public List<ColumnOrSuperColumn> get_multi_slice(MultiSliceRequest request) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;

    /**
     * for each schema version present in the cluster, returns a list of nodes at that version.
     * hosts that do not respond will be under the key DatabaseDescriptor.INITIAL_VERSION.
     * the cluster is all on the same version if the size of the map is 1.
     */
    public Map<String,List<String>> describe_schema_versions() throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * list the defined keyspaces in this cluster
     */
    public List<KsDef> describe_keyspaces() throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * get the cluster name
     */
    public String describe_cluster_name() throws org.apache.thrift.TException;

    /**
     * get the thrift api version
     */
    public String describe_version() throws org.apache.thrift.TException;

    /**
     * get the token ring: a map of ranges to host addresses,
     * represented as a set of TokenRange instead of a map from range
     * to list of endpoints, because you can't use Thrift structs as
     * map keys:
     * https://issues.apache.org/jira/browse/THRIFT-162
     * 
     * for the same reason, we can't return a set here, even though
     * order is neither important nor predictable.
     * 
     * @param keyspace
     */
    public List<TokenRange> describe_ring(String keyspace) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * same as describe_ring, but considers only nodes in the local DC
     * 
     * @param keyspace
     */
    public List<TokenRange> describe_local_ring(String keyspace) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * get the mapping between token->node ip
     * without taking replication into consideration
     * https://issues.apache.org/jira/browse/CASSANDRA-4092
     */
    public Map<String,String> describe_token_map() throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * returns the partitioner used by this cluster
     */
    public String describe_partitioner() throws org.apache.thrift.TException;

    /**
     * returns the snitch used by this cluster
     */
    public String describe_snitch() throws org.apache.thrift.TException;

    /**
     * describe specified keyspace
     * 
     * @param keyspace
     */
    public KsDef describe_keyspace(String keyspace) throws NotFoundException, InvalidRequestException, org.apache.thrift.TException;

    /**
     * experimental API for hadoop/parallel query support.
     * may change violently and without warning.
     * 
     * returns list of token strings such that first subrange is (list[0], list[1]],
     * next is (list[1], list[2]], etc.
     * 
     * @param cfName
     * @param start_token
     * @param end_token
     * @param keys_per_split
     */
    public List<String> describe_splits(String cfName, String start_token, String end_token, int keys_per_split) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * Enables tracing for the next query in this connection and returns the UUID for that trace session
     * The next query will be traced idependently of trace probability and the returned UUID can be used to query the trace keyspace
     */
    public ByteBuffer trace_next_query() throws org.apache.thrift.TException;

    public List<CfSplit> describe_splits_ex(String cfName, String start_token, String end_token, int keys_per_split) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * adds a column family. returns the new schema id.
     * 
     * @param cf_def
     */
    public String system_add_column_family(CfDef cf_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * drops a column family. returns the new schema id.
     * 
     * @param column_family
     */
    public String system_drop_column_family(String column_family) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * adds a keyspace and any column families that are part of it. returns the new schema id.
     * 
     * @param ks_def
     */
    public String system_add_keyspace(KsDef ks_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * drops a keyspace and any column families that are part of it. returns the new schema id.
     * 
     * @param keyspace
     */
    public String system_drop_keyspace(String keyspace) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * updates properties of a keyspace. returns the new schema id.
     * 
     * @param ks_def
     */
    public String system_update_keyspace(KsDef ks_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * updates properties of a column family. returns the new schema id.
     * 
     * @param cf_def
     */
    public String system_update_column_family(CfDef cf_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.
     * 
     * @param query
     * @param compression
     */
    public CqlResult execute_cql_query(ByteBuffer query, Compression compression) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * Executes a CQL3 (Cassandra Query Language) statement and returns a
     * CqlResult containing the results.
     * 
     * @param query
     * @param compression
     * @param consistency
     */
    public CqlResult execute_cql3_query(ByteBuffer query, Compression compression, ConsistencyLevel consistency) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.
     * 
     * @param query
     * @param compression
     */
    public CqlPreparedResult prepare_cql_query(ByteBuffer query, Compression compression) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * Prepare a CQL3 (Cassandra Query Language) statement by compiling and returning
     * - the type of CQL statement
     * - an id token of the compiled CQL stored on the server side.
     * - a count of the discovered bound markers in the statement
     * 
     * @param query
     * @param compression
     */
    public CqlPreparedResult prepare_cql3_query(ByteBuffer query, Compression compression) throws InvalidRequestException, org.apache.thrift.TException;

    /**
     * @deprecated Throws InvalidRequestException since 2.2. Please use the CQL3 version instead.
     * 
     * @param itemId
     * @param values
     */
    public CqlResult execute_prepared_cql_query(int itemId, List<ByteBuffer> values) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * Executes a prepared CQL3 (Cassandra Query Language) statement by passing an id token, a list of variables
     * to bind, and the consistency level, and returns a CqlResult containing the results.
     * 
     * @param itemId
     * @param values
     * @param consistency
     */
    public CqlResult execute_prepared_cql3_query(int itemId, List<ByteBuffer> values, ConsistencyLevel consistency) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException;

    /**
     * @deprecated This is now a no-op. Please use the CQL3 specific methods instead.
     * 
     * @param version
     */
    public void set_cql_version(String version) throws InvalidRequestException, org.apache.thrift.TException;

  }

  public interface AsyncIface {

    public void login(AuthenticationRequest auth_request, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void set_keyspace(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get_count(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void multiget_slice(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void multiget_count(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get_paged_slice(String column_family, KeyRange range, ByteBuffer start_column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, ConsistencyLevel serial_consistency_level, ConsistencyLevel commit_consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void atomic_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void truncate(String cfname, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void get_multi_slice(MultiSliceRequest request, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_schema_versions(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_keyspaces(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_cluster_name(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_version(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_ring(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_local_ring(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_token_map(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_partitioner(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_snitch(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_keyspace(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_splits(String cfName, String start_token, String end_token, int keys_per_split, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void trace_next_query(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void describe_splits_ex(String cfName, String start_token, String end_token, int keys_per_split, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void system_add_column_family(CfDef cf_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void system_drop_column_family(String column_family, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void system_add_keyspace(KsDef ks_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void system_drop_keyspace(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void system_update_keyspace(KsDef ks_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void system_update_column_family(CfDef cf_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void execute_cql_query(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void execute_cql3_query(ByteBuffer query, Compression compression, ConsistencyLevel consistency, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void prepare_cql_query(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void prepare_cql3_query(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void execute_prepared_cql_query(int itemId, List<ByteBuffer> values, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void execute_prepared_cql3_query(int itemId, List<ByteBuffer> values, ConsistencyLevel consistency, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;

    public void set_cql_version(String version, org.apache.thrift.async.AsyncMethodCallback 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 void login(AuthenticationRequest auth_request) throws AuthenticationException, AuthorizationException, org.apache.thrift.TException
    {
      send_login(auth_request);
      recv_login();
    }

    public void send_login(AuthenticationRequest auth_request) throws org.apache.thrift.TException
    {
      login_args args = new login_args();
      args.setAuth_request(auth_request);
      sendBase("login", args);
    }

    public void recv_login() throws AuthenticationException, AuthorizationException, org.apache.thrift.TException
    {
      login_result result = new login_result();
      receiveBase(result, "login");
      if (result.authnx != null) {
        throw result.authnx;
      }
      if (result.authzx != null) {
        throw result.authzx;
      }
      return;
    }

    public void set_keyspace(String keyspace) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_set_keyspace(keyspace);
      recv_set_keyspace();
    }

    public void send_set_keyspace(String keyspace) throws org.apache.thrift.TException
    {
      set_keyspace_args args = new set_keyspace_args();
      args.setKeyspace(keyspace);
      sendBase("set_keyspace", args);
    }

    public void recv_set_keyspace() throws InvalidRequestException, org.apache.thrift.TException
    {
      set_keyspace_result result = new set_keyspace_result();
      receiveBase(result, "set_keyspace");
      if (result.ire != null) {
        throw result.ire;
      }
      return;
    }

    public ColumnOrSuperColumn get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get(key, column_path, consistency_level);
      return recv_get();
    }

    public void send_get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      get_args args = new get_args();
      args.setKey(key);
      args.setColumn_path(column_path);
      args.setConsistency_level(consistency_level);
      sendBase("get", args);
    }

    public ColumnOrSuperColumn recv_get() throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_result result = new get_result();
      receiveBase(result, "get");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.nfe != null) {
        throw result.nfe;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get failed: unknown result");
    }

    public List<ColumnOrSuperColumn> get_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get_slice(key, column_parent, predicate, consistency_level);
      return recv_get_slice();
    }

    public void send_get_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      get_slice_args args = new get_slice_args();
      args.setKey(key);
      args.setColumn_parent(column_parent);
      args.setPredicate(predicate);
      args.setConsistency_level(consistency_level);
      sendBase("get_slice", args);
    }

    public List<ColumnOrSuperColumn> recv_get_slice() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_slice_result result = new get_slice_result();
      receiveBase(result, "get_slice");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get_slice failed: unknown result");
    }

    public int get_count(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get_count(key, column_parent, predicate, consistency_level);
      return recv_get_count();
    }

    public void send_get_count(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      get_count_args args = new get_count_args();
      args.setKey(key);
      args.setColumn_parent(column_parent);
      args.setPredicate(predicate);
      args.setConsistency_level(consistency_level);
      sendBase("get_count", args);
    }

    public int recv_get_count() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_count_result result = new get_count_result();
      receiveBase(result, "get_count");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get_count failed: unknown result");
    }

    public Map<ByteBuffer,List<ColumnOrSuperColumn>> multiget_slice(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_multiget_slice(keys, column_parent, predicate, consistency_level);
      return recv_multiget_slice();
    }

    public void send_multiget_slice(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      multiget_slice_args args = new multiget_slice_args();
      args.setKeys(keys);
      args.setColumn_parent(column_parent);
      args.setPredicate(predicate);
      args.setConsistency_level(consistency_level);
      sendBase("multiget_slice", args);
    }

    public Map<ByteBuffer,List<ColumnOrSuperColumn>> recv_multiget_slice() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      multiget_slice_result result = new multiget_slice_result();
      receiveBase(result, "multiget_slice");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "multiget_slice failed: unknown result");
    }

    public Map<ByteBuffer,Integer> multiget_count(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_multiget_count(keys, column_parent, predicate, consistency_level);
      return recv_multiget_count();
    }

    public void send_multiget_count(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      multiget_count_args args = new multiget_count_args();
      args.setKeys(keys);
      args.setColumn_parent(column_parent);
      args.setPredicate(predicate);
      args.setConsistency_level(consistency_level);
      sendBase("multiget_count", args);
    }

    public Map<ByteBuffer,Integer> recv_multiget_count() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      multiget_count_result result = new multiget_count_result();
      receiveBase(result, "multiget_count");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "multiget_count failed: unknown result");
    }

    public List<KeySlice> get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get_range_slices(column_parent, predicate, range, consistency_level);
      return recv_get_range_slices();
    }

    public void send_get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      get_range_slices_args args = new get_range_slices_args();
      args.setColumn_parent(column_parent);
      args.setPredicate(predicate);
      args.setRange(range);
      args.setConsistency_level(consistency_level);
      sendBase("get_range_slices", args);
    }

    public List<KeySlice> recv_get_range_slices() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_range_slices_result result = new get_range_slices_result();
      receiveBase(result, "get_range_slices");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get_range_slices failed: unknown result");
    }

    public List<KeySlice> get_paged_slice(String column_family, KeyRange range, ByteBuffer start_column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get_paged_slice(column_family, range, start_column, consistency_level);
      return recv_get_paged_slice();
    }

    public void send_get_paged_slice(String column_family, KeyRange range, ByteBuffer start_column, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      get_paged_slice_args args = new get_paged_slice_args();
      args.setColumn_family(column_family);
      args.setRange(range);
      args.setStart_column(start_column);
      args.setConsistency_level(consistency_level);
      sendBase("get_paged_slice", args);
    }

    public List<KeySlice> recv_get_paged_slice() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_paged_slice_result result = new get_paged_slice_result();
      receiveBase(result, "get_paged_slice");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get_paged_slice failed: unknown result");
    }

    public List<KeySlice> get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get_indexed_slices(column_parent, index_clause, column_predicate, consistency_level);
      return recv_get_indexed_slices();
    }

    public void send_get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      get_indexed_slices_args args = new get_indexed_slices_args();
      args.setColumn_parent(column_parent);
      args.setIndex_clause(index_clause);
      args.setColumn_predicate(column_predicate);
      args.setConsistency_level(consistency_level);
      sendBase("get_indexed_slices", args);
    }

    public List<KeySlice> recv_get_indexed_slices() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_indexed_slices_result result = new get_indexed_slices_result();
      receiveBase(result, "get_indexed_slices");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get_indexed_slices failed: unknown result");
    }

    public void insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_insert(key, column_parent, column, consistency_level);
      recv_insert();
    }

    public void send_insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      insert_args args = new insert_args();
      args.setKey(key);
      args.setColumn_parent(column_parent);
      args.setColumn(column);
      args.setConsistency_level(consistency_level);
      sendBase("insert", args);
    }

    public void recv_insert() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      insert_result result = new insert_result();
      receiveBase(result, "insert");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_add(key, column_parent, column, consistency_level);
      recv_add();
    }

    public void send_add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      add_args args = new add_args();
      args.setKey(key);
      args.setColumn_parent(column_parent);
      args.setColumn(column);
      args.setConsistency_level(consistency_level);
      sendBase("add", args);
    }

    public void recv_add() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      add_result result = new add_result();
      receiveBase(result, "add");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public CASResult cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, ConsistencyLevel serial_consistency_level, ConsistencyLevel commit_consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_cas(key, column_family, expected, updates, serial_consistency_level, commit_consistency_level);
      return recv_cas();
    }

    public void send_cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, ConsistencyLevel serial_consistency_level, ConsistencyLevel commit_consistency_level) throws org.apache.thrift.TException
    {
      cas_args args = new cas_args();
      args.setKey(key);
      args.setColumn_family(column_family);
      args.setExpected(expected);
      args.setUpdates(updates);
      args.setSerial_consistency_level(serial_consistency_level);
      args.setCommit_consistency_level(commit_consistency_level);
      sendBase("cas", args);
    }

    public CASResult recv_cas() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      cas_result result = new cas_result();
      receiveBase(result, "cas");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "cas failed: unknown result");
    }

    public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_remove(key, column_path, timestamp, consistency_level);
      recv_remove();
    }

    public void send_remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      remove_args args = new remove_args();
      args.setKey(key);
      args.setColumn_path(column_path);
      args.setTimestamp(timestamp);
      args.setConsistency_level(consistency_level);
      sendBase("remove", args);
    }

    public void recv_remove() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      remove_result result = new remove_result();
      receiveBase(result, "remove");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_remove_counter(key, path, consistency_level);
      recv_remove_counter();
    }

    public void send_remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      remove_counter_args args = new remove_counter_args();
      args.setKey(key);
      args.setPath(path);
      args.setConsistency_level(consistency_level);
      sendBase("remove_counter", args);
    }

    public void recv_remove_counter() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      remove_counter_result result = new remove_counter_result();
      receiveBase(result, "remove_counter");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public void batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_batch_mutate(mutation_map, consistency_level);
      recv_batch_mutate();
    }

    public void send_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      batch_mutate_args args = new batch_mutate_args();
      args.setMutation_map(mutation_map);
      args.setConsistency_level(consistency_level);
      sendBase("batch_mutate", args);
    }

    public void recv_batch_mutate() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      batch_mutate_result result = new batch_mutate_result();
      receiveBase(result, "batch_mutate");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public void atomic_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_atomic_batch_mutate(mutation_map, consistency_level);
      recv_atomic_batch_mutate();
    }

    public void send_atomic_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level) throws org.apache.thrift.TException
    {
      atomic_batch_mutate_args args = new atomic_batch_mutate_args();
      args.setMutation_map(mutation_map);
      args.setConsistency_level(consistency_level);
      sendBase("atomic_batch_mutate", args);
    }

    public void recv_atomic_batch_mutate() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      atomic_batch_mutate_result result = new atomic_batch_mutate_result();
      receiveBase(result, "atomic_batch_mutate");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public void truncate(String cfname) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_truncate(cfname);
      recv_truncate();
    }

    public void send_truncate(String cfname) throws org.apache.thrift.TException
    {
      truncate_args args = new truncate_args();
      args.setCfname(cfname);
      sendBase("truncate", args);
    }

    public void recv_truncate() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      truncate_result result = new truncate_result();
      receiveBase(result, "truncate");
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      return;
    }

    public List<ColumnOrSuperColumn> get_multi_slice(MultiSliceRequest request) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      send_get_multi_slice(request);
      return recv_get_multi_slice();
    }

    public void send_get_multi_slice(MultiSliceRequest request) throws org.apache.thrift.TException
    {
      get_multi_slice_args args = new get_multi_slice_args();
      args.setRequest(request);
      sendBase("get_multi_slice", args);
    }

    public List<ColumnOrSuperColumn> recv_get_multi_slice() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
    {
      get_multi_slice_result result = new get_multi_slice_result();
      receiveBase(result, "get_multi_slice");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "get_multi_slice failed: unknown result");
    }

    public Map<String,List<String>> describe_schema_versions() throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_schema_versions();
      return recv_describe_schema_versions();
    }

    public void send_describe_schema_versions() throws org.apache.thrift.TException
    {
      describe_schema_versions_args args = new describe_schema_versions_args();
      sendBase("describe_schema_versions", args);
    }

    public Map<String,List<String>> recv_describe_schema_versions() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_schema_versions_result result = new describe_schema_versions_result();
      receiveBase(result, "describe_schema_versions");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_schema_versions failed: unknown result");
    }

    public List<KsDef> describe_keyspaces() throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_keyspaces();
      return recv_describe_keyspaces();
    }

    public void send_describe_keyspaces() throws org.apache.thrift.TException
    {
      describe_keyspaces_args args = new describe_keyspaces_args();
      sendBase("describe_keyspaces", args);
    }

    public List<KsDef> recv_describe_keyspaces() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_keyspaces_result result = new describe_keyspaces_result();
      receiveBase(result, "describe_keyspaces");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_keyspaces failed: unknown result");
    }

    public String describe_cluster_name() throws org.apache.thrift.TException
    {
      send_describe_cluster_name();
      return recv_describe_cluster_name();
    }

    public void send_describe_cluster_name() throws org.apache.thrift.TException
    {
      describe_cluster_name_args args = new describe_cluster_name_args();
      sendBase("describe_cluster_name", args);
    }

    public String recv_describe_cluster_name() throws org.apache.thrift.TException
    {
      describe_cluster_name_result result = new describe_cluster_name_result();
      receiveBase(result, "describe_cluster_name");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_cluster_name failed: unknown result");
    }

    public String describe_version() throws org.apache.thrift.TException
    {
      send_describe_version();
      return recv_describe_version();
    }

    public void send_describe_version() throws org.apache.thrift.TException
    {
      describe_version_args args = new describe_version_args();
      sendBase("describe_version", args);
    }

    public String recv_describe_version() throws org.apache.thrift.TException
    {
      describe_version_result result = new describe_version_result();
      receiveBase(result, "describe_version");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_version failed: unknown result");
    }

    public List<TokenRange> describe_ring(String keyspace) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_ring(keyspace);
      return recv_describe_ring();
    }

    public void send_describe_ring(String keyspace) throws org.apache.thrift.TException
    {
      describe_ring_args args = new describe_ring_args();
      args.setKeyspace(keyspace);
      sendBase("describe_ring", args);
    }

    public List<TokenRange> recv_describe_ring() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_ring_result result = new describe_ring_result();
      receiveBase(result, "describe_ring");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_ring failed: unknown result");
    }

    public List<TokenRange> describe_local_ring(String keyspace) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_local_ring(keyspace);
      return recv_describe_local_ring();
    }

    public void send_describe_local_ring(String keyspace) throws org.apache.thrift.TException
    {
      describe_local_ring_args args = new describe_local_ring_args();
      args.setKeyspace(keyspace);
      sendBase("describe_local_ring", args);
    }

    public List<TokenRange> recv_describe_local_ring() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_local_ring_result result = new describe_local_ring_result();
      receiveBase(result, "describe_local_ring");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_local_ring failed: unknown result");
    }

    public Map<String,String> describe_token_map() throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_token_map();
      return recv_describe_token_map();
    }

    public void send_describe_token_map() throws org.apache.thrift.TException
    {
      describe_token_map_args args = new describe_token_map_args();
      sendBase("describe_token_map", args);
    }

    public Map<String,String> recv_describe_token_map() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_token_map_result result = new describe_token_map_result();
      receiveBase(result, "describe_token_map");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_token_map failed: unknown result");
    }

    public String describe_partitioner() throws org.apache.thrift.TException
    {
      send_describe_partitioner();
      return recv_describe_partitioner();
    }

    public void send_describe_partitioner() throws org.apache.thrift.TException
    {
      describe_partitioner_args args = new describe_partitioner_args();
      sendBase("describe_partitioner", args);
    }

    public String recv_describe_partitioner() throws org.apache.thrift.TException
    {
      describe_partitioner_result result = new describe_partitioner_result();
      receiveBase(result, "describe_partitioner");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_partitioner failed: unknown result");
    }

    public String describe_snitch() throws org.apache.thrift.TException
    {
      send_describe_snitch();
      return recv_describe_snitch();
    }

    public void send_describe_snitch() throws org.apache.thrift.TException
    {
      describe_snitch_args args = new describe_snitch_args();
      sendBase("describe_snitch", args);
    }

    public String recv_describe_snitch() throws org.apache.thrift.TException
    {
      describe_snitch_result result = new describe_snitch_result();
      receiveBase(result, "describe_snitch");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_snitch failed: unknown result");
    }

    public KsDef describe_keyspace(String keyspace) throws NotFoundException, InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_keyspace(keyspace);
      return recv_describe_keyspace();
    }

    public void send_describe_keyspace(String keyspace) throws org.apache.thrift.TException
    {
      describe_keyspace_args args = new describe_keyspace_args();
      args.setKeyspace(keyspace);
      sendBase("describe_keyspace", args);
    }

    public KsDef recv_describe_keyspace() throws NotFoundException, InvalidRequestException, org.apache.thrift.TException
    {
      describe_keyspace_result result = new describe_keyspace_result();
      receiveBase(result, "describe_keyspace");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.nfe != null) {
        throw result.nfe;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_keyspace failed: unknown result");
    }

    public List<String> describe_splits(String cfName, String start_token, String end_token, int keys_per_split) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_splits(cfName, start_token, end_token, keys_per_split);
      return recv_describe_splits();
    }

    public void send_describe_splits(String cfName, String start_token, String end_token, int keys_per_split) throws org.apache.thrift.TException
    {
      describe_splits_args args = new describe_splits_args();
      args.setCfName(cfName);
      args.setStart_token(start_token);
      args.setEnd_token(end_token);
      args.setKeys_per_split(keys_per_split);
      sendBase("describe_splits", args);
    }

    public List<String> recv_describe_splits() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_splits_result result = new describe_splits_result();
      receiveBase(result, "describe_splits");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_splits failed: unknown result");
    }

    public ByteBuffer trace_next_query() throws org.apache.thrift.TException
    {
      send_trace_next_query();
      return recv_trace_next_query();
    }

    public void send_trace_next_query() throws org.apache.thrift.TException
    {
      trace_next_query_args args = new trace_next_query_args();
      sendBase("trace_next_query", args);
    }

    public ByteBuffer recv_trace_next_query() throws org.apache.thrift.TException
    {
      trace_next_query_result result = new trace_next_query_result();
      receiveBase(result, "trace_next_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "trace_next_query failed: unknown result");
    }

    public List<CfSplit> describe_splits_ex(String cfName, String start_token, String end_token, int keys_per_split) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_describe_splits_ex(cfName, start_token, end_token, keys_per_split);
      return recv_describe_splits_ex();
    }

    public void send_describe_splits_ex(String cfName, String start_token, String end_token, int keys_per_split) throws org.apache.thrift.TException
    {
      describe_splits_ex_args args = new describe_splits_ex_args();
      args.setCfName(cfName);
      args.setStart_token(start_token);
      args.setEnd_token(end_token);
      args.setKeys_per_split(keys_per_split);
      sendBase("describe_splits_ex", args);
    }

    public List<CfSplit> recv_describe_splits_ex() throws InvalidRequestException, org.apache.thrift.TException
    {
      describe_splits_ex_result result = new describe_splits_ex_result();
      receiveBase(result, "describe_splits_ex");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "describe_splits_ex failed: unknown result");
    }

    public String system_add_column_family(CfDef cf_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_system_add_column_family(cf_def);
      return recv_system_add_column_family();
    }

    public void send_system_add_column_family(CfDef cf_def) throws org.apache.thrift.TException
    {
      system_add_column_family_args args = new system_add_column_family_args();
      args.setCf_def(cf_def);
      sendBase("system_add_column_family", args);
    }

    public String recv_system_add_column_family() throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      system_add_column_family_result result = new system_add_column_family_result();
      receiveBase(result, "system_add_column_family");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "system_add_column_family failed: unknown result");
    }

    public String system_drop_column_family(String column_family) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_system_drop_column_family(column_family);
      return recv_system_drop_column_family();
    }

    public void send_system_drop_column_family(String column_family) throws org.apache.thrift.TException
    {
      system_drop_column_family_args args = new system_drop_column_family_args();
      args.setColumn_family(column_family);
      sendBase("system_drop_column_family", args);
    }

    public String recv_system_drop_column_family() throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      system_drop_column_family_result result = new system_drop_column_family_result();
      receiveBase(result, "system_drop_column_family");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "system_drop_column_family failed: unknown result");
    }

    public String system_add_keyspace(KsDef ks_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_system_add_keyspace(ks_def);
      return recv_system_add_keyspace();
    }

    public void send_system_add_keyspace(KsDef ks_def) throws org.apache.thrift.TException
    {
      system_add_keyspace_args args = new system_add_keyspace_args();
      args.setKs_def(ks_def);
      sendBase("system_add_keyspace", args);
    }

    public String recv_system_add_keyspace() throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      system_add_keyspace_result result = new system_add_keyspace_result();
      receiveBase(result, "system_add_keyspace");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "system_add_keyspace failed: unknown result");
    }

    public String system_drop_keyspace(String keyspace) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_system_drop_keyspace(keyspace);
      return recv_system_drop_keyspace();
    }

    public void send_system_drop_keyspace(String keyspace) throws org.apache.thrift.TException
    {
      system_drop_keyspace_args args = new system_drop_keyspace_args();
      args.setKeyspace(keyspace);
      sendBase("system_drop_keyspace", args);
    }

    public String recv_system_drop_keyspace() throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      system_drop_keyspace_result result = new system_drop_keyspace_result();
      receiveBase(result, "system_drop_keyspace");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "system_drop_keyspace failed: unknown result");
    }

    public String system_update_keyspace(KsDef ks_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_system_update_keyspace(ks_def);
      return recv_system_update_keyspace();
    }

    public void send_system_update_keyspace(KsDef ks_def) throws org.apache.thrift.TException
    {
      system_update_keyspace_args args = new system_update_keyspace_args();
      args.setKs_def(ks_def);
      sendBase("system_update_keyspace", args);
    }

    public String recv_system_update_keyspace() throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      system_update_keyspace_result result = new system_update_keyspace_result();
      receiveBase(result, "system_update_keyspace");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "system_update_keyspace failed: unknown result");
    }

    public String system_update_column_family(CfDef cf_def) throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_system_update_column_family(cf_def);
      return recv_system_update_column_family();
    }

    public void send_system_update_column_family(CfDef cf_def) throws org.apache.thrift.TException
    {
      system_update_column_family_args args = new system_update_column_family_args();
      args.setCf_def(cf_def);
      sendBase("system_update_column_family", args);
    }

    public String recv_system_update_column_family() throws InvalidRequestException, SchemaDisagreementException, org.apache.thrift.TException
    {
      system_update_column_family_result result = new system_update_column_family_result();
      receiveBase(result, "system_update_column_family");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "system_update_column_family failed: unknown result");
    }

    public CqlResult execute_cql_query(ByteBuffer query, Compression compression) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_execute_cql_query(query, compression);
      return recv_execute_cql_query();
    }

    public void send_execute_cql_query(ByteBuffer query, Compression compression) throws org.apache.thrift.TException
    {
      execute_cql_query_args args = new execute_cql_query_args();
      args.setQuery(query);
      args.setCompression(compression);
      sendBase("execute_cql_query", args);
    }

    public CqlResult recv_execute_cql_query() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      execute_cql_query_result result = new execute_cql_query_result();
      receiveBase(result, "execute_cql_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute_cql_query failed: unknown result");
    }

    public CqlResult execute_cql3_query(ByteBuffer query, Compression compression, ConsistencyLevel consistency) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_execute_cql3_query(query, compression, consistency);
      return recv_execute_cql3_query();
    }

    public void send_execute_cql3_query(ByteBuffer query, Compression compression, ConsistencyLevel consistency) throws org.apache.thrift.TException
    {
      execute_cql3_query_args args = new execute_cql3_query_args();
      args.setQuery(query);
      args.setCompression(compression);
      args.setConsistency(consistency);
      sendBase("execute_cql3_query", args);
    }

    public CqlResult recv_execute_cql3_query() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      execute_cql3_query_result result = new execute_cql3_query_result();
      receiveBase(result, "execute_cql3_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute_cql3_query failed: unknown result");
    }

    public CqlPreparedResult prepare_cql_query(ByteBuffer query, Compression compression) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_prepare_cql_query(query, compression);
      return recv_prepare_cql_query();
    }

    public void send_prepare_cql_query(ByteBuffer query, Compression compression) throws org.apache.thrift.TException
    {
      prepare_cql_query_args args = new prepare_cql_query_args();
      args.setQuery(query);
      args.setCompression(compression);
      sendBase("prepare_cql_query", args);
    }

    public CqlPreparedResult recv_prepare_cql_query() throws InvalidRequestException, org.apache.thrift.TException
    {
      prepare_cql_query_result result = new prepare_cql_query_result();
      receiveBase(result, "prepare_cql_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "prepare_cql_query failed: unknown result");
    }

    public CqlPreparedResult prepare_cql3_query(ByteBuffer query, Compression compression) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_prepare_cql3_query(query, compression);
      return recv_prepare_cql3_query();
    }

    public void send_prepare_cql3_query(ByteBuffer query, Compression compression) throws org.apache.thrift.TException
    {
      prepare_cql3_query_args args = new prepare_cql3_query_args();
      args.setQuery(query);
      args.setCompression(compression);
      sendBase("prepare_cql3_query", args);
    }

    public CqlPreparedResult recv_prepare_cql3_query() throws InvalidRequestException, org.apache.thrift.TException
    {
      prepare_cql3_query_result result = new prepare_cql3_query_result();
      receiveBase(result, "prepare_cql3_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "prepare_cql3_query failed: unknown result");
    }

    public CqlResult execute_prepared_cql_query(int itemId, List<ByteBuffer> values) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_execute_prepared_cql_query(itemId, values);
      return recv_execute_prepared_cql_query();
    }

    public void send_execute_prepared_cql_query(int itemId, List<ByteBuffer> values) throws org.apache.thrift.TException
    {
      execute_prepared_cql_query_args args = new execute_prepared_cql_query_args();
      args.setItemId(itemId);
      args.setValues(values);
      sendBase("execute_prepared_cql_query", args);
    }

    public CqlResult recv_execute_prepared_cql_query() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      execute_prepared_cql_query_result result = new execute_prepared_cql_query_result();
      receiveBase(result, "execute_prepared_cql_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute_prepared_cql_query failed: unknown result");
    }

    public CqlResult execute_prepared_cql3_query(int itemId, List<ByteBuffer> values, ConsistencyLevel consistency) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      send_execute_prepared_cql3_query(itemId, values, consistency);
      return recv_execute_prepared_cql3_query();
    }

    public void send_execute_prepared_cql3_query(int itemId, List<ByteBuffer> values, ConsistencyLevel consistency) throws org.apache.thrift.TException
    {
      execute_prepared_cql3_query_args args = new execute_prepared_cql3_query_args();
      args.setItemId(itemId);
      args.setValues(values);
      args.setConsistency(consistency);
      sendBase("execute_prepared_cql3_query", args);
    }

    public CqlResult recv_execute_prepared_cql3_query() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, org.apache.thrift.TException
    {
      execute_prepared_cql3_query_result result = new execute_prepared_cql3_query_result();
      receiveBase(result, "execute_prepared_cql3_query");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.ire != null) {
        throw result.ire;
      }
      if (result.ue != null) {
        throw result.ue;
      }
      if (result.te != null) {
        throw result.te;
      }
      if (result.sde != null) {
        throw result.sde;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute_prepared_cql3_query failed: unknown result");
    }

    public void set_cql_version(String version) throws InvalidRequestException, org.apache.thrift.TException
    {
      send_set_cql_version(version);
      recv_set_cql_version();
    }

    public void send_set_cql_version(String version) throws org.apache.thrift.TException
    {
      set_cql_version_args args = new set_cql_version_args();
      args.setVersion(version);
      sendBase("set_cql_version", args);
    }

    public void recv_set_cql_version() throws InvalidRequestException, org.apache.thrift.TException
    {
      set_cql_version_result result = new set_cql_version_result();
      receiveBase(result, "set_cql_version");
      if (result.ire != null) {
        throw result.ire;
      }
      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 login(AuthenticationRequest auth_request, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      login_call method_call = new login_call(auth_request, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class login_call extends org.apache.thrift.async.TAsyncMethodCall {
      private AuthenticationRequest auth_request;
      public login_call(AuthenticationRequest auth_request, org.apache.thrift.async.AsyncMethodCallback 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.auth_request = auth_request;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("login", org.apache.thrift.protocol.TMessageType.CALL, 0));
        login_args args = new login_args();
        args.setAuth_request(auth_request);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws AuthenticationException, AuthorizationException, 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_login();
      }
    }

    public void set_keyspace(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      set_keyspace_call method_call = new set_keyspace_call(keyspace, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class set_keyspace_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String keyspace;
      public set_keyspace_call(String keyspace, org.apache.thrift.async.AsyncMethodCallback 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.keyspace = keyspace;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("set_keyspace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        set_keyspace_args args = new set_keyspace_args();
        args.setKeyspace(keyspace);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, 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_set_keyspace();
      }
    }

    public void get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_call method_call = new get_call(key, column_path, consistency_level, 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 key;
      private ColumnPath column_path;
      private ConsistencyLevel consistency_level;
      public get_call(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_path = column_path;
        this.consistency_level = consistency_level;
      }

      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.setKey(key);
        args.setColumn_path(column_path);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public ColumnOrSuperColumn getResult() throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, 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 get_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_slice_call method_call = new get_slice_call(key, column_parent, predicate, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_slice_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private ColumnParent column_parent;
      private SlicePredicate predicate;
      private ConsistencyLevel consistency_level;
      public get_slice_call(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_parent = column_parent;
        this.predicate = predicate;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get_slice", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_slice_args args = new get_slice_args();
        args.setKey(key);
        args.setColumn_parent(column_parent);
        args.setPredicate(predicate);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<ColumnOrSuperColumn> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_slice();
      }
    }

    public void get_count(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_count_call method_call = new get_count_call(key, column_parent, predicate, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_count_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private ColumnParent column_parent;
      private SlicePredicate predicate;
      private ConsistencyLevel consistency_level;
      public get_count_call(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_parent = column_parent;
        this.predicate = predicate;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get_count", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_count_args args = new get_count_args();
        args.setKey(key);
        args.setColumn_parent(column_parent);
        args.setPredicate(predicate);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public int getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_count();
      }
    }

    public void multiget_slice(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      multiget_slice_call method_call = new multiget_slice_call(keys, column_parent, predicate, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class multiget_slice_call extends org.apache.thrift.async.TAsyncMethodCall {
      private List<ByteBuffer> keys;
      private ColumnParent column_parent;
      private SlicePredicate predicate;
      private ConsistencyLevel consistency_level;
      public multiget_slice_call(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.keys = keys;
        this.column_parent = column_parent;
        this.predicate = predicate;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("multiget_slice", org.apache.thrift.protocol.TMessageType.CALL, 0));
        multiget_slice_args args = new multiget_slice_args();
        args.setKeys(keys);
        args.setColumn_parent(column_parent);
        args.setPredicate(predicate);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Map<ByteBuffer,List<ColumnOrSuperColumn>> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_multiget_slice();
      }
    }

    public void multiget_count(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      multiget_count_call method_call = new multiget_count_call(keys, column_parent, predicate, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class multiget_count_call extends org.apache.thrift.async.TAsyncMethodCall {
      private List<ByteBuffer> keys;
      private ColumnParent column_parent;
      private SlicePredicate predicate;
      private ConsistencyLevel consistency_level;
      public multiget_count_call(List<ByteBuffer> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.keys = keys;
        this.column_parent = column_parent;
        this.predicate = predicate;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("multiget_count", org.apache.thrift.protocol.TMessageType.CALL, 0));
        multiget_count_args args = new multiget_count_args();
        args.setKeys(keys);
        args.setColumn_parent(column_parent);
        args.setPredicate(predicate);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Map<ByteBuffer,Integer> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_multiget_count();
      }
    }

    public void get_range_slices(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_range_slices_call method_call = new get_range_slices_call(column_parent, predicate, range, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_range_slices_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ColumnParent column_parent;
      private SlicePredicate predicate;
      private KeyRange range;
      private ConsistencyLevel consistency_level;
      public get_range_slices_call(ColumnParent column_parent, SlicePredicate predicate, KeyRange range, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.column_parent = column_parent;
        this.predicate = predicate;
        this.range = range;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get_range_slices", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_range_slices_args args = new get_range_slices_args();
        args.setColumn_parent(column_parent);
        args.setPredicate(predicate);
        args.setRange(range);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<KeySlice> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_range_slices();
      }
    }

    public void get_paged_slice(String column_family, KeyRange range, ByteBuffer start_column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_paged_slice_call method_call = new get_paged_slice_call(column_family, range, start_column, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_paged_slice_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String column_family;
      private KeyRange range;
      private ByteBuffer start_column;
      private ConsistencyLevel consistency_level;
      public get_paged_slice_call(String column_family, KeyRange range, ByteBuffer start_column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.column_family = column_family;
        this.range = range;
        this.start_column = start_column;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get_paged_slice", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_paged_slice_args args = new get_paged_slice_args();
        args.setColumn_family(column_family);
        args.setRange(range);
        args.setStart_column(start_column);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<KeySlice> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_paged_slice();
      }
    }

    public void get_indexed_slices(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_indexed_slices_call method_call = new get_indexed_slices_call(column_parent, index_clause, column_predicate, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_indexed_slices_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ColumnParent column_parent;
      private IndexClause index_clause;
      private SlicePredicate column_predicate;
      private ConsistencyLevel consistency_level;
      public get_indexed_slices_call(ColumnParent column_parent, IndexClause index_clause, SlicePredicate column_predicate, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.column_parent = column_parent;
        this.index_clause = index_clause;
        this.column_predicate = column_predicate;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get_indexed_slices", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_indexed_slices_args args = new get_indexed_slices_args();
        args.setColumn_parent(column_parent);
        args.setIndex_clause(index_clause);
        args.setColumn_predicate(column_predicate);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<KeySlice> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_indexed_slices();
      }
    }

    public void insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      insert_call method_call = new insert_call(key, column_parent, column, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class insert_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private ColumnParent column_parent;
      private Column column;
      private ConsistencyLevel consistency_level;
      public insert_call(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_parent = column_parent;
        this.column = column;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("insert", org.apache.thrift.protocol.TMessageType.CALL, 0));
        insert_args args = new insert_args();
        args.setKey(key);
        args.setColumn_parent(column_parent);
        args.setColumn(column);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_insert();
      }
    }

    public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      add_call method_call = new add_call(key, column_parent, column, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class add_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private ColumnParent column_parent;
      private CounterColumn column;
      private ConsistencyLevel consistency_level;
      public add_call(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_parent = column_parent;
        this.column = column;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("add", org.apache.thrift.protocol.TMessageType.CALL, 0));
        add_args args = new add_args();
        args.setKey(key);
        args.setColumn_parent(column_parent);
        args.setColumn(column);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_add();
      }
    }

    public void cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, ConsistencyLevel serial_consistency_level, ConsistencyLevel commit_consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      cas_call method_call = new cas_call(key, column_family, expected, updates, serial_consistency_level, commit_consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class cas_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private String column_family;
      private List<Column> expected;
      private List<Column> updates;
      private ConsistencyLevel serial_consistency_level;
      private ConsistencyLevel commit_consistency_level;
      public cas_call(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, ConsistencyLevel serial_consistency_level, ConsistencyLevel commit_consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_family = column_family;
        this.expected = expected;
        this.updates = updates;
        this.serial_consistency_level = serial_consistency_level;
        this.commit_consistency_level = commit_consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("cas", org.apache.thrift.protocol.TMessageType.CALL, 0));
        cas_args args = new cas_args();
        args.setKey(key);
        args.setColumn_family(column_family);
        args.setExpected(expected);
        args.setUpdates(updates);
        args.setSerial_consistency_level(serial_consistency_level);
        args.setCommit_consistency_level(commit_consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CASResult getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_cas();
      }
    }

    public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      remove_call method_call = new remove_call(key, column_path, timestamp, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class remove_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private ColumnPath column_path;
      private long timestamp;
      private ConsistencyLevel consistency_level;
      public remove_call(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.column_path = column_path;
        this.timestamp = timestamp;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("remove", org.apache.thrift.protocol.TMessageType.CALL, 0));
        remove_args args = new remove_args();
        args.setKey(key);
        args.setColumn_path(column_path);
        args.setTimestamp(timestamp);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_remove();
      }
    }

    public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      remove_counter_call method_call = new remove_counter_call(key, path, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class remove_counter_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer key;
      private ColumnPath path;
      private ConsistencyLevel consistency_level;
      public remove_counter_call(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.key = key;
        this.path = path;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("remove_counter", org.apache.thrift.protocol.TMessageType.CALL, 0));
        remove_counter_args args = new remove_counter_args();
        args.setKey(key);
        args.setPath(path);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_remove_counter();
      }
    }

    public void batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      batch_mutate_call method_call = new batch_mutate_call(mutation_map, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class batch_mutate_call extends org.apache.thrift.async.TAsyncMethodCall {
      private Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map;
      private ConsistencyLevel consistency_level;
      public batch_mutate_call(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.mutation_map = mutation_map;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("batch_mutate", org.apache.thrift.protocol.TMessageType.CALL, 0));
        batch_mutate_args args = new batch_mutate_args();
        args.setMutation_map(mutation_map);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_batch_mutate();
      }
    }

    public void atomic_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      atomic_batch_mutate_call method_call = new atomic_batch_mutate_call(mutation_map, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class atomic_batch_mutate_call extends org.apache.thrift.async.TAsyncMethodCall {
      private Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map;
      private ConsistencyLevel consistency_level;
      public atomic_batch_mutate_call(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback 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.mutation_map = mutation_map;
        this.consistency_level = consistency_level;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("atomic_batch_mutate", org.apache.thrift.protocol.TMessageType.CALL, 0));
        atomic_batch_mutate_args args = new atomic_batch_mutate_args();
        args.setMutation_map(mutation_map);
        args.setConsistency_level(consistency_level);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_atomic_batch_mutate();
      }
    }

    public void truncate(String cfname, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      truncate_call method_call = new truncate_call(cfname, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class truncate_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String cfname;
      public truncate_call(String cfname, org.apache.thrift.async.AsyncMethodCallback 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.cfname = cfname;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("truncate", org.apache.thrift.protocol.TMessageType.CALL, 0));
        truncate_args args = new truncate_args();
        args.setCfname(cfname);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_truncate();
      }
    }

    public void get_multi_slice(MultiSliceRequest request, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      get_multi_slice_call method_call = new get_multi_slice_call(request, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class get_multi_slice_call extends org.apache.thrift.async.TAsyncMethodCall {
      private MultiSliceRequest request;
      public get_multi_slice_call(MultiSliceRequest request, org.apache.thrift.async.AsyncMethodCallback 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.request = request;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("get_multi_slice", org.apache.thrift.protocol.TMessageType.CALL, 0));
        get_multi_slice_args args = new get_multi_slice_args();
        args.setRequest(request);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<ColumnOrSuperColumn> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, 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_multi_slice();
      }
    }

    public void describe_schema_versions(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_schema_versions_call method_call = new describe_schema_versions_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_schema_versions_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_schema_versions_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public Map<String,List<String>> getResult() throws InvalidRequestException, 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_describe_schema_versions();
      }
    }

    public void describe_keyspaces(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_keyspaces_call method_call = new describe_keyspaces_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_keyspaces_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_keyspaces_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public List<KsDef> getResult() throws InvalidRequestException, 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_describe_keyspaces();
      }
    }

    public void describe_cluster_name(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_cluster_name_call method_call = new describe_cluster_name_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_cluster_name_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_cluster_name_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public String getResult() throws 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_describe_cluster_name();
      }
    }

    public void describe_version(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_version_call method_call = new describe_version_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_version_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_version_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public String getResult() throws 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_describe_version();
      }
    }

    public void describe_ring(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_ring_call method_call = new describe_ring_call(keyspace, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_ring_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String keyspace;
      public describe_ring_call(String keyspace, org.apache.thrift.async.AsyncMethodCallback 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.keyspace = keyspace;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("describe_ring", org.apache.thrift.protocol.TMessageType.CALL, 0));
        describe_ring_args args = new describe_ring_args();
        args.setKeyspace(keyspace);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<TokenRange> getResult() throws InvalidRequestException, 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_describe_ring();
      }
    }

    public void describe_local_ring(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_local_ring_call method_call = new describe_local_ring_call(keyspace, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_local_ring_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String keyspace;
      public describe_local_ring_call(String keyspace, org.apache.thrift.async.AsyncMethodCallback 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.keyspace = keyspace;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("describe_local_ring", org.apache.thrift.protocol.TMessageType.CALL, 0));
        describe_local_ring_args args = new describe_local_ring_args();
        args.setKeyspace(keyspace);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<TokenRange> getResult() throws InvalidRequestException, 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_describe_local_ring();
      }
    }

    public void describe_token_map(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_token_map_call method_call = new describe_token_map_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_token_map_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_token_map_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public Map<String,String> getResult() throws InvalidRequestException, 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_describe_token_map();
      }
    }

    public void describe_partitioner(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_partitioner_call method_call = new describe_partitioner_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_partitioner_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_partitioner_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public String getResult() throws 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_describe_partitioner();
      }
    }

    public void describe_snitch(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_snitch_call method_call = new describe_snitch_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_snitch_call extends org.apache.thrift.async.TAsyncMethodCall {
      public describe_snitch_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public String getResult() throws 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_describe_snitch();
      }
    }

    public void describe_keyspace(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_keyspace_call method_call = new describe_keyspace_call(keyspace, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_keyspace_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String keyspace;
      public describe_keyspace_call(String keyspace, org.apache.thrift.async.AsyncMethodCallback 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.keyspace = keyspace;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("describe_keyspace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        describe_keyspace_args args = new describe_keyspace_args();
        args.setKeyspace(keyspace);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public KsDef getResult() throws NotFoundException, InvalidRequestException, 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_describe_keyspace();
      }
    }

    public void describe_splits(String cfName, String start_token, String end_token, int keys_per_split, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_splits_call method_call = new describe_splits_call(cfName, start_token, end_token, keys_per_split, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_splits_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String cfName;
      private String start_token;
      private String end_token;
      private int keys_per_split;
      public describe_splits_call(String cfName, String start_token, String end_token, int keys_per_split, org.apache.thrift.async.AsyncMethodCallback 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.cfName = cfName;
        this.start_token = start_token;
        this.end_token = end_token;
        this.keys_per_split = keys_per_split;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("describe_splits", org.apache.thrift.protocol.TMessageType.CALL, 0));
        describe_splits_args args = new describe_splits_args();
        args.setCfName(cfName);
        args.setStart_token(start_token);
        args.setEnd_token(end_token);
        args.setKeys_per_split(keys_per_split);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<String> getResult() throws InvalidRequestException, 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_describe_splits();
      }
    }

    public void trace_next_query(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      trace_next_query_call method_call = new trace_next_query_call(resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class trace_next_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      public trace_next_query_call(org.apache.thrift.async.AsyncMethodCallback 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);
      }

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

      public ByteBuffer getResult() throws 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_trace_next_query();
      }
    }

    public void describe_splits_ex(String cfName, String start_token, String end_token, int keys_per_split, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      describe_splits_ex_call method_call = new describe_splits_ex_call(cfName, start_token, end_token, keys_per_split, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class describe_splits_ex_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String cfName;
      private String start_token;
      private String end_token;
      private int keys_per_split;
      public describe_splits_ex_call(String cfName, String start_token, String end_token, int keys_per_split, org.apache.thrift.async.AsyncMethodCallback 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.cfName = cfName;
        this.start_token = start_token;
        this.end_token = end_token;
        this.keys_per_split = keys_per_split;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("describe_splits_ex", org.apache.thrift.protocol.TMessageType.CALL, 0));
        describe_splits_ex_args args = new describe_splits_ex_args();
        args.setCfName(cfName);
        args.setStart_token(start_token);
        args.setEnd_token(end_token);
        args.setKeys_per_split(keys_per_split);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public List<CfSplit> getResult() throws InvalidRequestException, 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_describe_splits_ex();
      }
    }

    public void system_add_column_family(CfDef cf_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      system_add_column_family_call method_call = new system_add_column_family_call(cf_def, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class system_add_column_family_call extends org.apache.thrift.async.TAsyncMethodCall {
      private CfDef cf_def;
      public system_add_column_family_call(CfDef cf_def, org.apache.thrift.async.AsyncMethodCallback 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.cf_def = cf_def;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("system_add_column_family", org.apache.thrift.protocol.TMessageType.CALL, 0));
        system_add_column_family_args args = new system_add_column_family_args();
        args.setCf_def(cf_def);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws InvalidRequestException, SchemaDisagreementException, 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_system_add_column_family();
      }
    }

    public void system_drop_column_family(String column_family, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      system_drop_column_family_call method_call = new system_drop_column_family_call(column_family, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class system_drop_column_family_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String column_family;
      public system_drop_column_family_call(String column_family, org.apache.thrift.async.AsyncMethodCallback 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.column_family = column_family;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("system_drop_column_family", org.apache.thrift.protocol.TMessageType.CALL, 0));
        system_drop_column_family_args args = new system_drop_column_family_args();
        args.setColumn_family(column_family);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws InvalidRequestException, SchemaDisagreementException, 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_system_drop_column_family();
      }
    }

    public void system_add_keyspace(KsDef ks_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      system_add_keyspace_call method_call = new system_add_keyspace_call(ks_def, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class system_add_keyspace_call extends org.apache.thrift.async.TAsyncMethodCall {
      private KsDef ks_def;
      public system_add_keyspace_call(KsDef ks_def, org.apache.thrift.async.AsyncMethodCallback 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.ks_def = ks_def;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("system_add_keyspace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        system_add_keyspace_args args = new system_add_keyspace_args();
        args.setKs_def(ks_def);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws InvalidRequestException, SchemaDisagreementException, 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_system_add_keyspace();
      }
    }

    public void system_drop_keyspace(String keyspace, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      system_drop_keyspace_call method_call = new system_drop_keyspace_call(keyspace, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class system_drop_keyspace_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String keyspace;
      public system_drop_keyspace_call(String keyspace, org.apache.thrift.async.AsyncMethodCallback 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.keyspace = keyspace;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("system_drop_keyspace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        system_drop_keyspace_args args = new system_drop_keyspace_args();
        args.setKeyspace(keyspace);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws InvalidRequestException, SchemaDisagreementException, 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_system_drop_keyspace();
      }
    }

    public void system_update_keyspace(KsDef ks_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      system_update_keyspace_call method_call = new system_update_keyspace_call(ks_def, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class system_update_keyspace_call extends org.apache.thrift.async.TAsyncMethodCall {
      private KsDef ks_def;
      public system_update_keyspace_call(KsDef ks_def, org.apache.thrift.async.AsyncMethodCallback 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.ks_def = ks_def;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("system_update_keyspace", org.apache.thrift.protocol.TMessageType.CALL, 0));
        system_update_keyspace_args args = new system_update_keyspace_args();
        args.setKs_def(ks_def);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws InvalidRequestException, SchemaDisagreementException, 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_system_update_keyspace();
      }
    }

    public void system_update_column_family(CfDef cf_def, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      system_update_column_family_call method_call = new system_update_column_family_call(cf_def, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class system_update_column_family_call extends org.apache.thrift.async.TAsyncMethodCall {
      private CfDef cf_def;
      public system_update_column_family_call(CfDef cf_def, org.apache.thrift.async.AsyncMethodCallback 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.cf_def = cf_def;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("system_update_column_family", org.apache.thrift.protocol.TMessageType.CALL, 0));
        system_update_column_family_args args = new system_update_column_family_args();
        args.setCf_def(cf_def);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public String getResult() throws InvalidRequestException, SchemaDisagreementException, 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_system_update_column_family();
      }
    }

    public void execute_cql_query(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      execute_cql_query_call method_call = new execute_cql_query_call(query, compression, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class execute_cql_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer query;
      private Compression compression;
      public execute_cql_query_call(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback 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.query = query;
        this.compression = compression;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute_cql_query", org.apache.thrift.protocol.TMessageType.CALL, 0));
        execute_cql_query_args args = new execute_cql_query_args();
        args.setQuery(query);
        args.setCompression(compression);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CqlResult getResult() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, 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_execute_cql_query();
      }
    }

    public void execute_cql3_query(ByteBuffer query, Compression compression, ConsistencyLevel consistency, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      execute_cql3_query_call method_call = new execute_cql3_query_call(query, compression, consistency, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class execute_cql3_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer query;
      private Compression compression;
      private ConsistencyLevel consistency;
      public execute_cql3_query_call(ByteBuffer query, Compression compression, ConsistencyLevel consistency, org.apache.thrift.async.AsyncMethodCallback 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.query = query;
        this.compression = compression;
        this.consistency = consistency;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute_cql3_query", org.apache.thrift.protocol.TMessageType.CALL, 0));
        execute_cql3_query_args args = new execute_cql3_query_args();
        args.setQuery(query);
        args.setCompression(compression);
        args.setConsistency(consistency);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CqlResult getResult() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, 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_execute_cql3_query();
      }
    }

    public void prepare_cql_query(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      prepare_cql_query_call method_call = new prepare_cql_query_call(query, compression, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class prepare_cql_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer query;
      private Compression compression;
      public prepare_cql_query_call(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback 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.query = query;
        this.compression = compression;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("prepare_cql_query", org.apache.thrift.protocol.TMessageType.CALL, 0));
        prepare_cql_query_args args = new prepare_cql_query_args();
        args.setQuery(query);
        args.setCompression(compression);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CqlPreparedResult getResult() throws InvalidRequestException, 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_prepare_cql_query();
      }
    }

    public void prepare_cql3_query(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      prepare_cql3_query_call method_call = new prepare_cql3_query_call(query, compression, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class prepare_cql3_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      private ByteBuffer query;
      private Compression compression;
      public prepare_cql3_query_call(ByteBuffer query, Compression compression, org.apache.thrift.async.AsyncMethodCallback 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.query = query;
        this.compression = compression;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("prepare_cql3_query", org.apache.thrift.protocol.TMessageType.CALL, 0));
        prepare_cql3_query_args args = new prepare_cql3_query_args();
        args.setQuery(query);
        args.setCompression(compression);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CqlPreparedResult getResult() throws InvalidRequestException, 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_prepare_cql3_query();
      }
    }

    public void execute_prepared_cql_query(int itemId, List<ByteBuffer> values, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      execute_prepared_cql_query_call method_call = new execute_prepared_cql_query_call(itemId, values, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class execute_prepared_cql_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      private int itemId;
      private List<ByteBuffer> values;
      public execute_prepared_cql_query_call(int itemId, List<ByteBuffer> values, org.apache.thrift.async.AsyncMethodCallback 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.itemId = itemId;
        this.values = values;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute_prepared_cql_query", org.apache.thrift.protocol.TMessageType.CALL, 0));
        execute_prepared_cql_query_args args = new execute_prepared_cql_query_args();
        args.setItemId(itemId);
        args.setValues(values);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CqlResult getResult() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, 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_execute_prepared_cql_query();
      }
    }

    public void execute_prepared_cql3_query(int itemId, List<ByteBuffer> values, ConsistencyLevel consistency, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      execute_prepared_cql3_query_call method_call = new execute_prepared_cql3_query_call(itemId, values, consistency, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class execute_prepared_cql3_query_call extends org.apache.thrift.async.TAsyncMethodCall {
      private int itemId;
      private List<ByteBuffer> values;
      private ConsistencyLevel consistency;
      public execute_prepared_cql3_query_call(int itemId, List<ByteBuffer> values, ConsistencyLevel consistency, org.apache.thrift.async.AsyncMethodCallback 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.itemId = itemId;
        this.values = values;
        this.consistency = consistency;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute_prepared_cql3_query", org.apache.thrift.protocol.TMessageType.CALL, 0));
        execute_prepared_cql3_query_args args = new execute_prepared_cql3_query_args();
        args.setItemId(itemId);
        args.setValues(values);
        args.setConsistency(consistency);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public CqlResult getResult() throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, 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_execute_prepared_cql3_query();
      }
    }

    public void set_cql_version(String version, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
      checkReady();
      set_cql_version_call method_call = new set_cql_version_call(version, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class set_cql_version_call extends org.apache.thrift.async.TAsyncMethodCall {
      private String version;
      public set_cql_version_call(String version, org.apache.thrift.async.AsyncMethodCallback 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.version = version;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("set_cql_version", org.apache.thrift.protocol.TMessageType.CALL, 0));
        set_cql_version_args args = new set_cql_version_args();
        args.setVersion(version);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public void getResult() throws InvalidRequestException, 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_set_cql_version();
      }
    }

  }

  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("login", new login());
      processMap.put("set_keyspace", new set_keyspace());
      processMap.put("get", new get());
      processMap.put("get_slice", new get_slice());
      processMap.put("get_count", new get_count());
      processMap.put("multiget_slice", new multiget_slice());
      processMap.put("multiget_count", new multiget_count());
      processMap.put("get_range_slices", new get_range_slices());
      processMap.put("get_paged_slice", new get_paged_slice());
      processMap.put("get_indexed_slices", new get_indexed_slices());
      processMap.put("insert", new insert());
      processMap.put("add", new add());
      processMap.put("cas", new cas());
      processMap.put("remove", new remove());
      processMap.put("remove_counter", new remove_counter());
      processMap.put("batch_mutate", new batch_mutate());
      processMap.put("atomic_batch_mutate", new atomic_batch_mutate());
      processMap.put("truncate", new truncate());
      processMap.put("get_multi_slice", new get_multi_slice());
      processMap.put("describe_schema_versions", new describe_schema_versions());
      processMap.put("describe_keyspaces", new describe_keyspaces());
      processMap.put("describe_cluster_name", new describe_cluster_name());
      processMap.put("describe_version", new describe_version());
      processMap.put("describe_ring", new describe_ring());
      processMap.put("describe_local_ring", new describe_local_ring());
      processMap.put("describe_token_map", new describe_token_map());
      processMap.put("describe_partitioner", new describe_partitioner());
      processMap.put("describe_snitch", new describe_snitch());
      processMap.put("describe_keyspace", new describe_keyspace());
      processMap.put("describe_splits", new describe_splits());
      processMap.put("trace_next_query", new trace_next_query());
      processMap.put("describe_splits_ex", new describe_splits_ex());
      processMap.put("system_add_column_family", new system_add_column_family());
      processMap.put("system_drop_column_family", new system_drop_column_family());
      processMap.put("system_add_keyspace", new system_add_keyspace());
      processMap.put("system_drop_keyspace", new system_drop_keyspace());
      processMap.put("system_update_keyspace", new system_update_keyspace());
      processMap.put("system_update_column_family", new system_update_column_family());
      processMap.put("execute_cql_query", new execute_cql_query());
      processMap.put("execute_cql3_query", new execute_cql3_query());
      processMap.put("prepare_cql_query", new prepare_cql_query());
      processMap.put("prepare_cql3_query", new prepare_cql3_query());
      processMap.put("execute_prepared_cql_query", new execute_prepared_cql_query());
      processMap.put("execute_prepared_cql3_query", new execute_prepared_cql3_query());
      processMap.put("set_cql_version", new set_cql_version());
      return processMap;
    }

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

      public login_args getEmptyArgsInstance() {
        return new login_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public login_result getResult(I iface, login_args args) throws org.apache.thrift.TException {
        login_result result = new login_result();
        try {
          iface.login(args.auth_request);
        } catch (AuthenticationException authnx) {
          result.authnx = authnx;
        } catch (AuthorizationException authzx) {
          result.authzx = authzx;
        }
        return result;
      }
    }

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

      public set_keyspace_args getEmptyArgsInstance() {
        return new set_keyspace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public set_keyspace_result getResult(I iface, set_keyspace_args args) throws org.apache.thrift.TException {
        set_keyspace_result result = new set_keyspace_result();
        try {
          iface.set_keyspace(args.keyspace);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

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

      protected boolean isOneway() {
        return false;
      }

      public 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.key, args.column_path, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (NotFoundException nfe) {
          result.nfe = nfe;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public get_slice_args getEmptyArgsInstance() {
        return new get_slice_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public get_slice_result getResult(I iface, get_slice_args args) throws org.apache.thrift.TException {
        get_slice_result result = new get_slice_result();
        try {
          result.success = iface.get_slice(args.key, args.column_parent, args.predicate, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public get_count_args getEmptyArgsInstance() {
        return new get_count_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public get_count_result getResult(I iface, get_count_args args) throws org.apache.thrift.TException {
        get_count_result result = new get_count_result();
        try {
          result.success = iface.get_count(args.key, args.column_parent, args.predicate, args.consistency_level);
          result.setSuccessIsSet(true);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public multiget_slice_args getEmptyArgsInstance() {
        return new multiget_slice_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public multiget_slice_result getResult(I iface, multiget_slice_args args) throws org.apache.thrift.TException {
        multiget_slice_result result = new multiget_slice_result();
        try {
          result.success = iface.multiget_slice(args.keys, args.column_parent, args.predicate, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public multiget_count_args getEmptyArgsInstance() {
        return new multiget_count_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public multiget_count_result getResult(I iface, multiget_count_args args) throws org.apache.thrift.TException {
        multiget_count_result result = new multiget_count_result();
        try {
          result.success = iface.multiget_count(args.keys, args.column_parent, args.predicate, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public get_range_slices_args getEmptyArgsInstance() {
        return new get_range_slices_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public get_range_slices_result getResult(I iface, get_range_slices_args args) throws org.apache.thrift.TException {
        get_range_slices_result result = new get_range_slices_result();
        try {
          result.success = iface.get_range_slices(args.column_parent, args.predicate, args.range, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public get_paged_slice_args getEmptyArgsInstance() {
        return new get_paged_slice_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public get_paged_slice_result getResult(I iface, get_paged_slice_args args) throws org.apache.thrift.TException {
        get_paged_slice_result result = new get_paged_slice_result();
        try {
          result.success = iface.get_paged_slice(args.column_family, args.range, args.start_column, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public get_indexed_slices_args getEmptyArgsInstance() {
        return new get_indexed_slices_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public get_indexed_slices_result getResult(I iface, get_indexed_slices_args args) throws org.apache.thrift.TException {
        get_indexed_slices_result result = new get_indexed_slices_result();
        try {
          result.success = iface.get_indexed_slices(args.column_parent, args.index_clause, args.column_predicate, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public insert_args getEmptyArgsInstance() {
        return new insert_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public insert_result getResult(I iface, insert_args args) throws org.apache.thrift.TException {
        insert_result result = new insert_result();
        try {
          iface.insert(args.key, args.column_parent, args.column, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public add_args getEmptyArgsInstance() {
        return new add_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public add_result getResult(I iface, add_args args) throws org.apache.thrift.TException {
        add_result result = new add_result();
        try {
          iface.add(args.key, args.column_parent, args.column, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public cas_args getEmptyArgsInstance() {
        return new cas_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public cas_result getResult(I iface, cas_args args) throws org.apache.thrift.TException {
        cas_result result = new cas_result();
        try {
          result.success = iface.cas(args.key, args.column_family, args.expected, args.updates, args.serial_consistency_level, args.commit_consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public remove_args getEmptyArgsInstance() {
        return new remove_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public remove_result getResult(I iface, remove_args args) throws org.apache.thrift.TException {
        remove_result result = new remove_result();
        try {
          iface.remove(args.key, args.column_path, args.timestamp, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public remove_counter_args getEmptyArgsInstance() {
        return new remove_counter_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public remove_counter_result getResult(I iface, remove_counter_args args) throws org.apache.thrift.TException {
        remove_counter_result result = new remove_counter_result();
        try {
          iface.remove_counter(args.key, args.path, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public batch_mutate_args getEmptyArgsInstance() {
        return new batch_mutate_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public batch_mutate_result getResult(I iface, batch_mutate_args args) throws org.apache.thrift.TException {
        batch_mutate_result result = new batch_mutate_result();
        try {
          iface.batch_mutate(args.mutation_map, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public atomic_batch_mutate_args getEmptyArgsInstance() {
        return new atomic_batch_mutate_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public atomic_batch_mutate_result getResult(I iface, atomic_batch_mutate_args args) throws org.apache.thrift.TException {
        atomic_batch_mutate_result result = new atomic_batch_mutate_result();
        try {
          iface.atomic_batch_mutate(args.mutation_map, args.consistency_level);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public truncate_args getEmptyArgsInstance() {
        return new truncate_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public truncate_result getResult(I iface, truncate_args args) throws org.apache.thrift.TException {
        truncate_result result = new truncate_result();
        try {
          iface.truncate(args.cfname);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public get_multi_slice_args getEmptyArgsInstance() {
        return new get_multi_slice_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public get_multi_slice_result getResult(I iface, get_multi_slice_args args) throws org.apache.thrift.TException {
        get_multi_slice_result result = new get_multi_slice_result();
        try {
          result.success = iface.get_multi_slice(args.request);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        }
        return result;
      }
    }

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

      public describe_schema_versions_args getEmptyArgsInstance() {
        return new describe_schema_versions_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_schema_versions_result getResult(I iface, describe_schema_versions_args args) throws org.apache.thrift.TException {
        describe_schema_versions_result result = new describe_schema_versions_result();
        try {
          result.success = iface.describe_schema_versions();
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public describe_keyspaces_args getEmptyArgsInstance() {
        return new describe_keyspaces_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_keyspaces_result getResult(I iface, describe_keyspaces_args args) throws org.apache.thrift.TException {
        describe_keyspaces_result result = new describe_keyspaces_result();
        try {
          result.success = iface.describe_keyspaces();
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public describe_cluster_name_args getEmptyArgsInstance() {
        return new describe_cluster_name_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_cluster_name_result getResult(I iface, describe_cluster_name_args args) throws org.apache.thrift.TException {
        describe_cluster_name_result result = new describe_cluster_name_result();
        result.success = iface.describe_cluster_name();
        return result;
      }
    }

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

      public describe_version_args getEmptyArgsInstance() {
        return new describe_version_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_version_result getResult(I iface, describe_version_args args) throws org.apache.thrift.TException {
        describe_version_result result = new describe_version_result();
        result.success = iface.describe_version();
        return result;
      }
    }

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

      public describe_ring_args getEmptyArgsInstance() {
        return new describe_ring_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_ring_result getResult(I iface, describe_ring_args args) throws org.apache.thrift.TException {
        describe_ring_result result = new describe_ring_result();
        try {
          result.success = iface.describe_ring(args.keyspace);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public describe_local_ring_args getEmptyArgsInstance() {
        return new describe_local_ring_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_local_ring_result getResult(I iface, describe_local_ring_args args) throws org.apache.thrift.TException {
        describe_local_ring_result result = new describe_local_ring_result();
        try {
          result.success = iface.describe_local_ring(args.keyspace);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public describe_token_map_args getEmptyArgsInstance() {
        return new describe_token_map_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_token_map_result getResult(I iface, describe_token_map_args args) throws org.apache.thrift.TException {
        describe_token_map_result result = new describe_token_map_result();
        try {
          result.success = iface.describe_token_map();
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public describe_partitioner_args getEmptyArgsInstance() {
        return new describe_partitioner_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_partitioner_result getResult(I iface, describe_partitioner_args args) throws org.apache.thrift.TException {
        describe_partitioner_result result = new describe_partitioner_result();
        result.success = iface.describe_partitioner();
        return result;
      }
    }

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

      public describe_snitch_args getEmptyArgsInstance() {
        return new describe_snitch_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_snitch_result getResult(I iface, describe_snitch_args args) throws org.apache.thrift.TException {
        describe_snitch_result result = new describe_snitch_result();
        result.success = iface.describe_snitch();
        return result;
      }
    }

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

      public describe_keyspace_args getEmptyArgsInstance() {
        return new describe_keyspace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_keyspace_result getResult(I iface, describe_keyspace_args args) throws org.apache.thrift.TException {
        describe_keyspace_result result = new describe_keyspace_result();
        try {
          result.success = iface.describe_keyspace(args.keyspace);
        } catch (NotFoundException nfe) {
          result.nfe = nfe;
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public describe_splits_args getEmptyArgsInstance() {
        return new describe_splits_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_splits_result getResult(I iface, describe_splits_args args) throws org.apache.thrift.TException {
        describe_splits_result result = new describe_splits_result();
        try {
          result.success = iface.describe_splits(args.cfName, args.start_token, args.end_token, args.keys_per_split);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public trace_next_query_args getEmptyArgsInstance() {
        return new trace_next_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public trace_next_query_result getResult(I iface, trace_next_query_args args) throws org.apache.thrift.TException {
        trace_next_query_result result = new trace_next_query_result();
        result.success = iface.trace_next_query();
        return result;
      }
    }

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

      public describe_splits_ex_args getEmptyArgsInstance() {
        return new describe_splits_ex_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public describe_splits_ex_result getResult(I iface, describe_splits_ex_args args) throws org.apache.thrift.TException {
        describe_splits_ex_result result = new describe_splits_ex_result();
        try {
          result.success = iface.describe_splits_ex(args.cfName, args.start_token, args.end_token, args.keys_per_split);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public system_add_column_family_args getEmptyArgsInstance() {
        return new system_add_column_family_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public system_add_column_family_result getResult(I iface, system_add_column_family_args args) throws org.apache.thrift.TException {
        system_add_column_family_result result = new system_add_column_family_result();
        try {
          result.success = iface.system_add_column_family(args.cf_def);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public system_drop_column_family_args getEmptyArgsInstance() {
        return new system_drop_column_family_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public system_drop_column_family_result getResult(I iface, system_drop_column_family_args args) throws org.apache.thrift.TException {
        system_drop_column_family_result result = new system_drop_column_family_result();
        try {
          result.success = iface.system_drop_column_family(args.column_family);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public system_add_keyspace_args getEmptyArgsInstance() {
        return new system_add_keyspace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public system_add_keyspace_result getResult(I iface, system_add_keyspace_args args) throws org.apache.thrift.TException {
        system_add_keyspace_result result = new system_add_keyspace_result();
        try {
          result.success = iface.system_add_keyspace(args.ks_def);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public system_drop_keyspace_args getEmptyArgsInstance() {
        return new system_drop_keyspace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public system_drop_keyspace_result getResult(I iface, system_drop_keyspace_args args) throws org.apache.thrift.TException {
        system_drop_keyspace_result result = new system_drop_keyspace_result();
        try {
          result.success = iface.system_drop_keyspace(args.keyspace);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public system_update_keyspace_args getEmptyArgsInstance() {
        return new system_update_keyspace_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public system_update_keyspace_result getResult(I iface, system_update_keyspace_args args) throws org.apache.thrift.TException {
        system_update_keyspace_result result = new system_update_keyspace_result();
        try {
          result.success = iface.system_update_keyspace(args.ks_def);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public system_update_column_family_args getEmptyArgsInstance() {
        return new system_update_column_family_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public system_update_column_family_result getResult(I iface, system_update_column_family_args args) throws org.apache.thrift.TException {
        system_update_column_family_result result = new system_update_column_family_result();
        try {
          result.success = iface.system_update_column_family(args.cf_def);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public execute_cql_query_args getEmptyArgsInstance() {
        return new execute_cql_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public execute_cql_query_result getResult(I iface, execute_cql_query_args args) throws org.apache.thrift.TException {
        execute_cql_query_result result = new execute_cql_query_result();
        try {
          result.success = iface.execute_cql_query(args.query, args.compression);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public execute_cql3_query_args getEmptyArgsInstance() {
        return new execute_cql3_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public execute_cql3_query_result getResult(I iface, execute_cql3_query_args args) throws org.apache.thrift.TException {
        execute_cql3_query_result result = new execute_cql3_query_result();
        try {
          result.success = iface.execute_cql3_query(args.query, args.compression, args.consistency);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public prepare_cql_query_args getEmptyArgsInstance() {
        return new prepare_cql_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public prepare_cql_query_result getResult(I iface, prepare_cql_query_args args) throws org.apache.thrift.TException {
        prepare_cql_query_result result = new prepare_cql_query_result();
        try {
          result.success = iface.prepare_cql_query(args.query, args.compression);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public prepare_cql3_query_args getEmptyArgsInstance() {
        return new prepare_cql3_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public prepare_cql3_query_result getResult(I iface, prepare_cql3_query_args args) throws org.apache.thrift.TException {
        prepare_cql3_query_result result = new prepare_cql3_query_result();
        try {
          result.success = iface.prepare_cql3_query(args.query, args.compression);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

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

      public execute_prepared_cql_query_args getEmptyArgsInstance() {
        return new execute_prepared_cql_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public execute_prepared_cql_query_result getResult(I iface, execute_prepared_cql_query_args args) throws org.apache.thrift.TException {
        execute_prepared_cql_query_result result = new execute_prepared_cql_query_result();
        try {
          result.success = iface.execute_prepared_cql_query(args.itemId, args.values);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public execute_prepared_cql3_query_args getEmptyArgsInstance() {
        return new execute_prepared_cql3_query_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public execute_prepared_cql3_query_result getResult(I iface, execute_prepared_cql3_query_args args) throws org.apache.thrift.TException {
        execute_prepared_cql3_query_result result = new execute_prepared_cql3_query_result();
        try {
          result.success = iface.execute_prepared_cql3_query(args.itemId, args.values, args.consistency);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        } catch (UnavailableException ue) {
          result.ue = ue;
        } catch (TimedOutException te) {
          result.te = te;
        } catch (SchemaDisagreementException sde) {
          result.sde = sde;
        }
        return result;
      }
    }

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

      public set_cql_version_args getEmptyArgsInstance() {
        return new set_cql_version_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public set_cql_version_result getResult(I iface, set_cql_version_args args) throws org.apache.thrift.TException {
        set_cql_version_result result = new set_cql_version_result();
        try {
          iface.set_cql_version(args.version);
        } catch (InvalidRequestException ire) {
          result.ire = ire;
        }
        return result;
      }
    }

  }

  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncProcessor.class.getName());
    public AsyncProcessor(I iface) {
      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
    }

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

    private static <I extends AsyncIface> Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      processMap.put("login", new login());
      processMap.put("set_keyspace", new set_keyspace());
      processMap.put("get", new get());
      processMap.put("get_slice", new get_slice());
      processMap.put("get_count", new get_count());
      processMap.put("multiget_slice", new multiget_slice());
      processMap.put("multiget_count", new multiget_count());
      processMap.put("get_range_slices", new get_range_slices());
      processMap.put("get_paged_slice", new get_paged_slice());
      processMap.put("get_indexed_slices", new get_indexed_slices());
      processMap.put("insert", new insert());
      processMap.put("add", new add());
      processMap.put("cas", new cas());
      processMap.put("remove", new remove());
      processMap.put("remove_counter", new remove_counter());
      processMap.put("batch_mutate", new batch_mutate());
      processMap.put("atomic_batch_mutate", new atomic_batch_mutate());
      processMap.put("truncate", new truncate());
      processMap.put("get_multi_slice", new get_multi_slice());
      processMap.put("describe_schema_versions", new describe_schema_versions());
      processMap.put("describe_keyspaces", new describe_keyspaces());
      processMap.put("describe_cluster_name", new describe_cluster_name());
      processMap.put("describe_version", new describe_version());
      processMap.put("describe_ring", new describe_ring());
      processMap.put("describe_local_ring", new describe_local_ring());
      processMap.put("describe_token_map", new describe_token_map());
      processMap.put("describe_partitioner", new describe_partitioner());
      processMap.put("describe_snitch", new describe_snitch());
      processMap.put("describe_keyspace", new describe_keyspace());
      processMap.put("describe_splits", new describe_splits());
      processMap.put("trace_next_query", new trace_next_query());
      processMap.put("describe_splits_ex", new describe_splits_ex());
      processMap.put("system_add_column_family", new system_add_column_family());
      processMap.put("system_drop_column_family", new system_drop_column_family());
      processMap.put("system_add_keyspace", new system_add_keyspace());
      processMap.put("system_drop_keyspace", new system_drop_keyspace());
      processMap.put("system_update_keyspace", new system_update_keyspace());
      processMap.put("system_update_column_family", new system_update_column_family());
      processMap.put("execute_cql_query", new execute_cql_query());
      processMap.put("execute_cql3_query", new execute_cql3_query());
      processMap.put("prepare_cql_query", new prepare_cql_query());
      processMap.put("prepare_cql3_query", new prepare_cql3_query());
      processMap.put("execute_prepared_cql_query", new execute_prepared_cql_query());
      processMap.put("execute_prepared_cql3_query", new execute_prepared_cql3_query());
      processMap.put("set_cql_version", new set_cql_version());
      return processMap;
    }

    public static class login<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, login_args, Void> {
      public login() {
        super("login");
      }

      public login_args getEmptyArgsInstance() {
        return new login_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            login_result result = new login_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            login_result result = new login_result();
            if (e instanceof AuthenticationException) {
                        result.authnx = (AuthenticationException) e;
                        result.setAuthnxIsSet(true);
                        msg = result;
            }
            else             if (e instanceof AuthorizationException) {
                        result.authzx = (AuthorizationException) e;
                        result.setAuthzxIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, login_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.login(args.auth_request,resultHandler);
      }
    }

    public static class set_keyspace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, set_keyspace_args, Void> {
      public set_keyspace() {
        super("set_keyspace");
      }

      public set_keyspace_args getEmptyArgsInstance() {
        return new set_keyspace_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            set_keyspace_result result = new set_keyspace_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            set_keyspace_result result = new set_keyspace_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, set_keyspace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.set_keyspace(args.keyspace,resultHandler);
      }
    }

    public static class get<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_args, ColumnOrSuperColumn> {
      public get() {
        super("get");
      }

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

      public AsyncMethodCallback<ColumnOrSuperColumn> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<ColumnOrSuperColumn>() { 
          public void onComplete(ColumnOrSuperColumn o) {
            get_result result = new get_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_result result = new get_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof NotFoundException) {
                        result.nfe = (NotFoundException) e;
                        result.setNfeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_args args, org.apache.thrift.async.AsyncMethodCallback<ColumnOrSuperColumn> resultHandler) throws TException {
        iface.get(args.key, args.column_path, args.consistency_level,resultHandler);
      }
    }

    public static class get_slice<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_slice_args, List<ColumnOrSuperColumn>> {
      public get_slice() {
        super("get_slice");
      }

      public get_slice_args getEmptyArgsInstance() {
        return new get_slice_args();
      }

      public AsyncMethodCallback<List<ColumnOrSuperColumn>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<ColumnOrSuperColumn>>() { 
          public void onComplete(List<ColumnOrSuperColumn> o) {
            get_slice_result result = new get_slice_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_slice_result result = new get_slice_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_slice_args args, org.apache.thrift.async.AsyncMethodCallback<List<ColumnOrSuperColumn>> resultHandler) throws TException {
        iface.get_slice(args.key, args.column_parent, args.predicate, args.consistency_level,resultHandler);
      }
    }

    public static class get_count<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_count_args, Integer> {
      public get_count() {
        super("get_count");
      }

      public get_count_args getEmptyArgsInstance() {
        return new get_count_args();
      }

      public AsyncMethodCallback<Integer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Integer>() { 
          public void onComplete(Integer o) {
            get_count_result result = new get_count_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_count_result result = new get_count_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_count_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws TException {
        iface.get_count(args.key, args.column_parent, args.predicate, args.consistency_level,resultHandler);
      }
    }

    public static class multiget_slice<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, multiget_slice_args, Map<ByteBuffer,List<ColumnOrSuperColumn>>> {
      public multiget_slice() {
        super("multiget_slice");
      }

      public multiget_slice_args getEmptyArgsInstance() {
        return new multiget_slice_args();
      }

      public AsyncMethodCallback<Map<ByteBuffer,List<ColumnOrSuperColumn>>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<ByteBuffer,List<ColumnOrSuperColumn>>>() { 
          public void onComplete(Map<ByteBuffer,List<ColumnOrSuperColumn>> o) {
            multiget_slice_result result = new multiget_slice_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            multiget_slice_result result = new multiget_slice_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, multiget_slice_args args, org.apache.thrift.async.AsyncMethodCallback<Map<ByteBuffer,List<ColumnOrSuperColumn>>> resultHandler) throws TException {
        iface.multiget_slice(args.keys, args.column_parent, args.predicate, args.consistency_level,resultHandler);
      }
    }

    public static class multiget_count<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, multiget_count_args, Map<ByteBuffer,Integer>> {
      public multiget_count() {
        super("multiget_count");
      }

      public multiget_count_args getEmptyArgsInstance() {
        return new multiget_count_args();
      }

      public AsyncMethodCallback<Map<ByteBuffer,Integer>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<ByteBuffer,Integer>>() { 
          public void onComplete(Map<ByteBuffer,Integer> o) {
            multiget_count_result result = new multiget_count_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            multiget_count_result result = new multiget_count_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, multiget_count_args args, org.apache.thrift.async.AsyncMethodCallback<Map<ByteBuffer,Integer>> resultHandler) throws TException {
        iface.multiget_count(args.keys, args.column_parent, args.predicate, args.consistency_level,resultHandler);
      }
    }

    public static class get_range_slices<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_range_slices_args, List<KeySlice>> {
      public get_range_slices() {
        super("get_range_slices");
      }

      public get_range_slices_args getEmptyArgsInstance() {
        return new get_range_slices_args();
      }

      public AsyncMethodCallback<List<KeySlice>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<KeySlice>>() { 
          public void onComplete(List<KeySlice> o) {
            get_range_slices_result result = new get_range_slices_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_range_slices_result result = new get_range_slices_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_range_slices_args args, org.apache.thrift.async.AsyncMethodCallback<List<KeySlice>> resultHandler) throws TException {
        iface.get_range_slices(args.column_parent, args.predicate, args.range, args.consistency_level,resultHandler);
      }
    }

    public static class get_paged_slice<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_paged_slice_args, List<KeySlice>> {
      public get_paged_slice() {
        super("get_paged_slice");
      }

      public get_paged_slice_args getEmptyArgsInstance() {
        return new get_paged_slice_args();
      }

      public AsyncMethodCallback<List<KeySlice>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<KeySlice>>() { 
          public void onComplete(List<KeySlice> o) {
            get_paged_slice_result result = new get_paged_slice_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_paged_slice_result result = new get_paged_slice_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_paged_slice_args args, org.apache.thrift.async.AsyncMethodCallback<List<KeySlice>> resultHandler) throws TException {
        iface.get_paged_slice(args.column_family, args.range, args.start_column, args.consistency_level,resultHandler);
      }
    }

    public static class get_indexed_slices<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_indexed_slices_args, List<KeySlice>> {
      public get_indexed_slices() {
        super("get_indexed_slices");
      }

      public get_indexed_slices_args getEmptyArgsInstance() {
        return new get_indexed_slices_args();
      }

      public AsyncMethodCallback<List<KeySlice>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<KeySlice>>() { 
          public void onComplete(List<KeySlice> o) {
            get_indexed_slices_result result = new get_indexed_slices_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_indexed_slices_result result = new get_indexed_slices_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_indexed_slices_args args, org.apache.thrift.async.AsyncMethodCallback<List<KeySlice>> resultHandler) throws TException {
        iface.get_indexed_slices(args.column_parent, args.index_clause, args.column_predicate, args.consistency_level,resultHandler);
      }
    }

    public static class insert<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, insert_args, Void> {
      public insert() {
        super("insert");
      }

      public insert_args getEmptyArgsInstance() {
        return new insert_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            insert_result result = new insert_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            insert_result result = new insert_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, insert_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.insert(args.key, args.column_parent, args.column, args.consistency_level,resultHandler);
      }
    }

    public static class add<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, add_args, Void> {
      public add() {
        super("add");
      }

      public add_args getEmptyArgsInstance() {
        return new add_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            add_result result = new add_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            add_result result = new add_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, add_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.add(args.key, args.column_parent, args.column, args.consistency_level,resultHandler);
      }
    }

    public static class cas<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, cas_args, CASResult> {
      public cas() {
        super("cas");
      }

      public cas_args getEmptyArgsInstance() {
        return new cas_args();
      }

      public AsyncMethodCallback<CASResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CASResult>() { 
          public void onComplete(CASResult o) {
            cas_result result = new cas_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            cas_result result = new cas_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, cas_args args, org.apache.thrift.async.AsyncMethodCallback<CASResult> resultHandler) throws TException {
        iface.cas(args.key, args.column_family, args.expected, args.updates, args.serial_consistency_level, args.commit_consistency_level,resultHandler);
      }
    }

    public static class remove<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, remove_args, Void> {
      public remove() {
        super("remove");
      }

      public remove_args getEmptyArgsInstance() {
        return new remove_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            remove_result result = new remove_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            remove_result result = new remove_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, remove_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.remove(args.key, args.column_path, args.timestamp, args.consistency_level,resultHandler);
      }
    }

    public static class remove_counter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, remove_counter_args, Void> {
      public remove_counter() {
        super("remove_counter");
      }

      public remove_counter_args getEmptyArgsInstance() {
        return new remove_counter_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            remove_counter_result result = new remove_counter_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            remove_counter_result result = new remove_counter_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, remove_counter_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.remove_counter(args.key, args.path, args.consistency_level,resultHandler);
      }
    }

    public static class batch_mutate<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, batch_mutate_args, Void> {
      public batch_mutate() {
        super("batch_mutate");
      }

      public batch_mutate_args getEmptyArgsInstance() {
        return new batch_mutate_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            batch_mutate_result result = new batch_mutate_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            batch_mutate_result result = new batch_mutate_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, batch_mutate_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.batch_mutate(args.mutation_map, args.consistency_level,resultHandler);
      }
    }

    public static class atomic_batch_mutate<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, atomic_batch_mutate_args, Void> {
      public atomic_batch_mutate() {
        super("atomic_batch_mutate");
      }

      public atomic_batch_mutate_args getEmptyArgsInstance() {
        return new atomic_batch_mutate_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            atomic_batch_mutate_result result = new atomic_batch_mutate_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            atomic_batch_mutate_result result = new atomic_batch_mutate_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, atomic_batch_mutate_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.atomic_batch_mutate(args.mutation_map, args.consistency_level,resultHandler);
      }
    }

    public static class truncate<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, truncate_args, Void> {
      public truncate() {
        super("truncate");
      }

      public truncate_args getEmptyArgsInstance() {
        return new truncate_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            truncate_result result = new truncate_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            truncate_result result = new truncate_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, truncate_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.truncate(args.cfname,resultHandler);
      }
    }

    public static class get_multi_slice<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, get_multi_slice_args, List<ColumnOrSuperColumn>> {
      public get_multi_slice() {
        super("get_multi_slice");
      }

      public get_multi_slice_args getEmptyArgsInstance() {
        return new get_multi_slice_args();
      }

      public AsyncMethodCallback<List<ColumnOrSuperColumn>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<ColumnOrSuperColumn>>() { 
          public void onComplete(List<ColumnOrSuperColumn> o) {
            get_multi_slice_result result = new get_multi_slice_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            get_multi_slice_result result = new get_multi_slice_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, get_multi_slice_args args, org.apache.thrift.async.AsyncMethodCallback<List<ColumnOrSuperColumn>> resultHandler) throws TException {
        iface.get_multi_slice(args.request,resultHandler);
      }
    }

    public static class describe_schema_versions<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_schema_versions_args, Map<String,List<String>>> {
      public describe_schema_versions() {
        super("describe_schema_versions");
      }

      public describe_schema_versions_args getEmptyArgsInstance() {
        return new describe_schema_versions_args();
      }

      public AsyncMethodCallback<Map<String,List<String>>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,List<String>>>() { 
          public void onComplete(Map<String,List<String>> o) {
            describe_schema_versions_result result = new describe_schema_versions_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_schema_versions_result result = new describe_schema_versions_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_schema_versions_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,List<String>>> resultHandler) throws TException {
        iface.describe_schema_versions(resultHandler);
      }
    }

    public static class describe_keyspaces<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_keyspaces_args, List<KsDef>> {
      public describe_keyspaces() {
        super("describe_keyspaces");
      }

      public describe_keyspaces_args getEmptyArgsInstance() {
        return new describe_keyspaces_args();
      }

      public AsyncMethodCallback<List<KsDef>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<KsDef>>() { 
          public void onComplete(List<KsDef> o) {
            describe_keyspaces_result result = new describe_keyspaces_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_keyspaces_result result = new describe_keyspaces_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_keyspaces_args args, org.apache.thrift.async.AsyncMethodCallback<List<KsDef>> resultHandler) throws TException {
        iface.describe_keyspaces(resultHandler);
      }
    }

    public static class describe_cluster_name<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_cluster_name_args, String> {
      public describe_cluster_name() {
        super("describe_cluster_name");
      }

      public describe_cluster_name_args getEmptyArgsInstance() {
        return new describe_cluster_name_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            describe_cluster_name_result result = new describe_cluster_name_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_cluster_name_result result = new describe_cluster_name_result();
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_cluster_name_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.describe_cluster_name(resultHandler);
      }
    }

    public static class describe_version<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_version_args, String> {
      public describe_version() {
        super("describe_version");
      }

      public describe_version_args getEmptyArgsInstance() {
        return new describe_version_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            describe_version_result result = new describe_version_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_version_result result = new describe_version_result();
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_version_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.describe_version(resultHandler);
      }
    }

    public static class describe_ring<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_ring_args, List<TokenRange>> {
      public describe_ring() {
        super("describe_ring");
      }

      public describe_ring_args getEmptyArgsInstance() {
        return new describe_ring_args();
      }

      public AsyncMethodCallback<List<TokenRange>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<TokenRange>>() { 
          public void onComplete(List<TokenRange> o) {
            describe_ring_result result = new describe_ring_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_ring_result result = new describe_ring_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_ring_args args, org.apache.thrift.async.AsyncMethodCallback<List<TokenRange>> resultHandler) throws TException {
        iface.describe_ring(args.keyspace,resultHandler);
      }
    }

    public static class describe_local_ring<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_local_ring_args, List<TokenRange>> {
      public describe_local_ring() {
        super("describe_local_ring");
      }

      public describe_local_ring_args getEmptyArgsInstance() {
        return new describe_local_ring_args();
      }

      public AsyncMethodCallback<List<TokenRange>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<TokenRange>>() { 
          public void onComplete(List<TokenRange> o) {
            describe_local_ring_result result = new describe_local_ring_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_local_ring_result result = new describe_local_ring_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_local_ring_args args, org.apache.thrift.async.AsyncMethodCallback<List<TokenRange>> resultHandler) throws TException {
        iface.describe_local_ring(args.keyspace,resultHandler);
      }
    }

    public static class describe_token_map<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_token_map_args, Map<String,String>> {
      public describe_token_map() {
        super("describe_token_map");
      }

      public describe_token_map_args getEmptyArgsInstance() {
        return new describe_token_map_args();
      }

      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Map<String,String>>() { 
          public void onComplete(Map<String,String> o) {
            describe_token_map_result result = new describe_token_map_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_token_map_result result = new describe_token_map_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_token_map_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
        iface.describe_token_map(resultHandler);
      }
    }

    public static class describe_partitioner<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_partitioner_args, String> {
      public describe_partitioner() {
        super("describe_partitioner");
      }

      public describe_partitioner_args getEmptyArgsInstance() {
        return new describe_partitioner_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            describe_partitioner_result result = new describe_partitioner_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_partitioner_result result = new describe_partitioner_result();
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_partitioner_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.describe_partitioner(resultHandler);
      }
    }

    public static class describe_snitch<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_snitch_args, String> {
      public describe_snitch() {
        super("describe_snitch");
      }

      public describe_snitch_args getEmptyArgsInstance() {
        return new describe_snitch_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            describe_snitch_result result = new describe_snitch_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_snitch_result result = new describe_snitch_result();
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_snitch_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.describe_snitch(resultHandler);
      }
    }

    public static class describe_keyspace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_keyspace_args, KsDef> {
      public describe_keyspace() {
        super("describe_keyspace");
      }

      public describe_keyspace_args getEmptyArgsInstance() {
        return new describe_keyspace_args();
      }

      public AsyncMethodCallback<KsDef> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<KsDef>() { 
          public void onComplete(KsDef o) {
            describe_keyspace_result result = new describe_keyspace_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_keyspace_result result = new describe_keyspace_result();
            if (e instanceof NotFoundException) {
                        result.nfe = (NotFoundException) e;
                        result.setNfeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_keyspace_args args, org.apache.thrift.async.AsyncMethodCallback<KsDef> resultHandler) throws TException {
        iface.describe_keyspace(args.keyspace,resultHandler);
      }
    }

    public static class describe_splits<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_splits_args, List<String>> {
      public describe_splits() {
        super("describe_splits");
      }

      public describe_splits_args getEmptyArgsInstance() {
        return new describe_splits_args();
      }

      public AsyncMethodCallback<List<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<String>>() { 
          public void onComplete(List<String> o) {
            describe_splits_result result = new describe_splits_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_splits_result result = new describe_splits_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_splits_args args, org.apache.thrift.async.AsyncMethodCallback<List<String>> resultHandler) throws TException {
        iface.describe_splits(args.cfName, args.start_token, args.end_token, args.keys_per_split,resultHandler);
      }
    }

    public static class trace_next_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, trace_next_query_args, ByteBuffer> {
      public trace_next_query() {
        super("trace_next_query");
      }

      public trace_next_query_args getEmptyArgsInstance() {
        return new trace_next_query_args();
      }

      public AsyncMethodCallback<ByteBuffer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<ByteBuffer>() { 
          public void onComplete(ByteBuffer o) {
            trace_next_query_result result = new trace_next_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            trace_next_query_result result = new trace_next_query_result();
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, trace_next_query_args args, org.apache.thrift.async.AsyncMethodCallback<ByteBuffer> resultHandler) throws TException {
        iface.trace_next_query(resultHandler);
      }
    }

    public static class describe_splits_ex<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, describe_splits_ex_args, List<CfSplit>> {
      public describe_splits_ex() {
        super("describe_splits_ex");
      }

      public describe_splits_ex_args getEmptyArgsInstance() {
        return new describe_splits_ex_args();
      }

      public AsyncMethodCallback<List<CfSplit>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<List<CfSplit>>() { 
          public void onComplete(List<CfSplit> o) {
            describe_splits_ex_result result = new describe_splits_ex_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            describe_splits_ex_result result = new describe_splits_ex_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, describe_splits_ex_args args, org.apache.thrift.async.AsyncMethodCallback<List<CfSplit>> resultHandler) throws TException {
        iface.describe_splits_ex(args.cfName, args.start_token, args.end_token, args.keys_per_split,resultHandler);
      }
    }

    public static class system_add_column_family<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, system_add_column_family_args, String> {
      public system_add_column_family() {
        super("system_add_column_family");
      }

      public system_add_column_family_args getEmptyArgsInstance() {
        return new system_add_column_family_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            system_add_column_family_result result = new system_add_column_family_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            system_add_column_family_result result = new system_add_column_family_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, system_add_column_family_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.system_add_column_family(args.cf_def,resultHandler);
      }
    }

    public static class system_drop_column_family<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, system_drop_column_family_args, String> {
      public system_drop_column_family() {
        super("system_drop_column_family");
      }

      public system_drop_column_family_args getEmptyArgsInstance() {
        return new system_drop_column_family_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            system_drop_column_family_result result = new system_drop_column_family_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            system_drop_column_family_result result = new system_drop_column_family_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, system_drop_column_family_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.system_drop_column_family(args.column_family,resultHandler);
      }
    }

    public static class system_add_keyspace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, system_add_keyspace_args, String> {
      public system_add_keyspace() {
        super("system_add_keyspace");
      }

      public system_add_keyspace_args getEmptyArgsInstance() {
        return new system_add_keyspace_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            system_add_keyspace_result result = new system_add_keyspace_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            system_add_keyspace_result result = new system_add_keyspace_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, system_add_keyspace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.system_add_keyspace(args.ks_def,resultHandler);
      }
    }

    public static class system_drop_keyspace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, system_drop_keyspace_args, String> {
      public system_drop_keyspace() {
        super("system_drop_keyspace");
      }

      public system_drop_keyspace_args getEmptyArgsInstance() {
        return new system_drop_keyspace_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            system_drop_keyspace_result result = new system_drop_keyspace_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            system_drop_keyspace_result result = new system_drop_keyspace_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, system_drop_keyspace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.system_drop_keyspace(args.keyspace,resultHandler);
      }
    }

    public static class system_update_keyspace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, system_update_keyspace_args, String> {
      public system_update_keyspace() {
        super("system_update_keyspace");
      }

      public system_update_keyspace_args getEmptyArgsInstance() {
        return new system_update_keyspace_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            system_update_keyspace_result result = new system_update_keyspace_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            system_update_keyspace_result result = new system_update_keyspace_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, system_update_keyspace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.system_update_keyspace(args.ks_def,resultHandler);
      }
    }

    public static class system_update_column_family<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, system_update_column_family_args, String> {
      public system_update_column_family() {
        super("system_update_column_family");
      }

      public system_update_column_family_args getEmptyArgsInstance() {
        return new system_update_column_family_args();
      }

      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<String>() { 
          public void onComplete(String o) {
            system_update_column_family_result result = new system_update_column_family_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            system_update_column_family_result result = new system_update_column_family_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, system_update_column_family_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
        iface.system_update_column_family(args.cf_def,resultHandler);
      }
    }

    public static class execute_cql_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_cql_query_args, CqlResult> {
      public execute_cql_query() {
        super("execute_cql_query");
      }

      public execute_cql_query_args getEmptyArgsInstance() {
        return new execute_cql_query_args();
      }

      public AsyncMethodCallback<CqlResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CqlResult>() { 
          public void onComplete(CqlResult o) {
            execute_cql_query_result result = new execute_cql_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            execute_cql_query_result result = new execute_cql_query_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, execute_cql_query_args args, org.apache.thrift.async.AsyncMethodCallback<CqlResult> resultHandler) throws TException {
        iface.execute_cql_query(args.query, args.compression,resultHandler);
      }
    }

    public static class execute_cql3_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_cql3_query_args, CqlResult> {
      public execute_cql3_query() {
        super("execute_cql3_query");
      }

      public execute_cql3_query_args getEmptyArgsInstance() {
        return new execute_cql3_query_args();
      }

      public AsyncMethodCallback<CqlResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CqlResult>() { 
          public void onComplete(CqlResult o) {
            execute_cql3_query_result result = new execute_cql3_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            execute_cql3_query_result result = new execute_cql3_query_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, execute_cql3_query_args args, org.apache.thrift.async.AsyncMethodCallback<CqlResult> resultHandler) throws TException {
        iface.execute_cql3_query(args.query, args.compression, args.consistency,resultHandler);
      }
    }

    public static class prepare_cql_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, prepare_cql_query_args, CqlPreparedResult> {
      public prepare_cql_query() {
        super("prepare_cql_query");
      }

      public prepare_cql_query_args getEmptyArgsInstance() {
        return new prepare_cql_query_args();
      }

      public AsyncMethodCallback<CqlPreparedResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CqlPreparedResult>() { 
          public void onComplete(CqlPreparedResult o) {
            prepare_cql_query_result result = new prepare_cql_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            prepare_cql_query_result result = new prepare_cql_query_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, prepare_cql_query_args args, org.apache.thrift.async.AsyncMethodCallback<CqlPreparedResult> resultHandler) throws TException {
        iface.prepare_cql_query(args.query, args.compression,resultHandler);
      }
    }

    public static class prepare_cql3_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, prepare_cql3_query_args, CqlPreparedResult> {
      public prepare_cql3_query() {
        super("prepare_cql3_query");
      }

      public prepare_cql3_query_args getEmptyArgsInstance() {
        return new prepare_cql3_query_args();
      }

      public AsyncMethodCallback<CqlPreparedResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CqlPreparedResult>() { 
          public void onComplete(CqlPreparedResult o) {
            prepare_cql3_query_result result = new prepare_cql3_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            prepare_cql3_query_result result = new prepare_cql3_query_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, prepare_cql3_query_args args, org.apache.thrift.async.AsyncMethodCallback<CqlPreparedResult> resultHandler) throws TException {
        iface.prepare_cql3_query(args.query, args.compression,resultHandler);
      }
    }

    public static class execute_prepared_cql_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_prepared_cql_query_args, CqlResult> {
      public execute_prepared_cql_query() {
        super("execute_prepared_cql_query");
      }

      public execute_prepared_cql_query_args getEmptyArgsInstance() {
        return new execute_prepared_cql_query_args();
      }

      public AsyncMethodCallback<CqlResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CqlResult>() { 
          public void onComplete(CqlResult o) {
            execute_prepared_cql_query_result result = new execute_prepared_cql_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            execute_prepared_cql_query_result result = new execute_prepared_cql_query_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, execute_prepared_cql_query_args args, org.apache.thrift.async.AsyncMethodCallback<CqlResult> resultHandler) throws TException {
        iface.execute_prepared_cql_query(args.itemId, args.values,resultHandler);
      }
    }

    public static class execute_prepared_cql3_query<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_prepared_cql3_query_args, CqlResult> {
      public execute_prepared_cql3_query() {
        super("execute_prepared_cql3_query");
      }

      public execute_prepared_cql3_query_args getEmptyArgsInstance() {
        return new execute_prepared_cql3_query_args();
      }

      public AsyncMethodCallback<CqlResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<CqlResult>() { 
          public void onComplete(CqlResult o) {
            execute_prepared_cql3_query_result result = new execute_prepared_cql3_query_result();
            result.success = o;
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            execute_prepared_cql3_query_result result = new execute_prepared_cql3_query_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
            else             if (e instanceof UnavailableException) {
                        result.ue = (UnavailableException) e;
                        result.setUeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof TimedOutException) {
                        result.te = (TimedOutException) e;
                        result.setTeIsSet(true);
                        msg = result;
            }
            else             if (e instanceof SchemaDisagreementException) {
                        result.sde = (SchemaDisagreementException) e;
                        result.setSdeIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, execute_prepared_cql3_query_args args, org.apache.thrift.async.AsyncMethodCallback<CqlResult> resultHandler) throws TException {
        iface.execute_prepared_cql3_query(args.itemId, args.values, args.consistency,resultHandler);
      }
    }

    public static class set_cql_version<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, set_cql_version_args, Void> {
      public set_cql_version() {
        super("set_cql_version");
      }

      public set_cql_version_args getEmptyArgsInstance() {
        return new set_cql_version_args();
      }

      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            set_cql_version_result result = new set_cql_version_result();
            try {
              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
              return;
            } catch (Exception e) {
              LOGGER.error("Exception writing to internal frame buffer", e);
            }
            fb.close();
          }
          public void onError(Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TBase msg;
            set_cql_version_result result = new set_cql_version_result();
            if (e instanceof InvalidRequestException) {
                        result.ire = (InvalidRequestException) e;
                        result.setIreIsSet(true);
                        msg = result;
            }
             else 
            {
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
              return;
            } catch (Exception ex) {
              LOGGER.error("Exception writing to internal frame buffer", ex);
            }
            fb.close();
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, set_cql_version_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
        iface.set_cql_version(args.version,resultHandler);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField AUTH_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("auth_request", 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 login_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new login_argsTupleSchemeFactory());
    }

    public AuthenticationRequest auth_request; // 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 {
      AUTH_REQUEST((short)1, "auth_request");

      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: // AUTH_REQUEST
            return AUTH_REQUEST;
          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.AUTH_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("auth_request", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AuthenticationRequest.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(login_args.class, metaDataMap);
    }

    public login_args() {
    }

    public login_args(
      AuthenticationRequest auth_request)
    {
      this();
      this.auth_request = auth_request;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public login_args(login_args other) {
      if (other.isSetAuth_request()) {
        this.auth_request = new AuthenticationRequest(other.auth_request);
      }
    }

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

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

    public AuthenticationRequest getAuth_request() {
      return this.auth_request;
    }

    public login_args setAuth_request(AuthenticationRequest auth_request) {
      this.auth_request = auth_request;
      return this;
    }

    public void unsetAuth_request() {
      this.auth_request = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTH_REQUEST:
        if (value == null) {
          unsetAuth_request();
        } else {
          setAuth_request((AuthenticationRequest)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTH_REQUEST:
        return getAuth_request();

      }
      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 AUTH_REQUEST:
        return isSetAuth_request();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_auth_request = true && this.isSetAuth_request();
      boolean that_present_auth_request = true && that.isSetAuth_request();
      if (this_present_auth_request || that_present_auth_request) {
        if (!(this_present_auth_request && that_present_auth_request))
          return false;
        if (!this.auth_request.equals(that.auth_request))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_auth_request = true && (isSetAuth_request());
      builder.append(present_auth_request);
      if (present_auth_request)
        builder.append(auth_request);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetAuth_request()).compareTo(other.isSetAuth_request());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuth_request()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.auth_request, other.auth_request);
        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("login_args(");
      boolean first = true;

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

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

    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 login_argsStandardSchemeFactory implements SchemeFactory {
      public login_argsStandardScheme getScheme() {
        return new login_argsStandardScheme();
      }
    }

    private static class login_argsStandardScheme extends StandardScheme<login_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, login_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: // AUTH_REQUEST
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.auth_request = new AuthenticationRequest();
                struct.auth_request.read(iprot);
                struct.setAuth_requestIsSet(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, login_args struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class login_argsTupleSchemeFactory implements SchemeFactory {
      public login_argsTupleScheme getScheme() {
        return new login_argsTupleScheme();
      }
    }

    private static class login_argsTupleScheme extends TupleScheme<login_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, login_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.auth_request = new AuthenticationRequest();
        struct.auth_request.read(iprot);
        struct.setAuth_requestIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField AUTHNX_FIELD_DESC = new org.apache.thrift.protocol.TField("authnx", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField AUTHZX_FIELD_DESC = new org.apache.thrift.protocol.TField("authzx", 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 login_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new login_resultTupleSchemeFactory());
    }

    public AuthenticationException authnx; // required
    public AuthorizationException authzx; // 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 {
      AUTHNX((short)1, "authnx"),
      AUTHZX((short)2, "authzx");

      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: // AUTHNX
            return AUTHNX;
          case 2: // AUTHZX
            return AUTHZX;
          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.AUTHNX, new org.apache.thrift.meta_data.FieldMetaData("authnx", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.AUTHZX, new org.apache.thrift.meta_data.FieldMetaData("authzx", 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(login_result.class, metaDataMap);
    }

    public login_result() {
    }

    public login_result(
      AuthenticationException authnx,
      AuthorizationException authzx)
    {
      this();
      this.authnx = authnx;
      this.authzx = authzx;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public login_result(login_result other) {
      if (other.isSetAuthnx()) {
        this.authnx = new AuthenticationException(other.authnx);
      }
      if (other.isSetAuthzx()) {
        this.authzx = new AuthorizationException(other.authzx);
      }
    }

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

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

    public AuthenticationException getAuthnx() {
      return this.authnx;
    }

    public login_result setAuthnx(AuthenticationException authnx) {
      this.authnx = authnx;
      return this;
    }

    public void unsetAuthnx() {
      this.authnx = null;
    }

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

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

    public AuthorizationException getAuthzx() {
      return this.authzx;
    }

    public login_result setAuthzx(AuthorizationException authzx) {
      this.authzx = authzx;
      return this;
    }

    public void unsetAuthzx() {
      this.authzx = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case AUTHNX:
        if (value == null) {
          unsetAuthnx();
        } else {
          setAuthnx((AuthenticationException)value);
        }
        break;

      case AUTHZX:
        if (value == null) {
          unsetAuthzx();
        } else {
          setAuthzx((AuthorizationException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case AUTHNX:
        return getAuthnx();

      case AUTHZX:
        return getAuthzx();

      }
      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 AUTHNX:
        return isSetAuthnx();
      case AUTHZX:
        return isSetAuthzx();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_authnx = true && this.isSetAuthnx();
      boolean that_present_authnx = true && that.isSetAuthnx();
      if (this_present_authnx || that_present_authnx) {
        if (!(this_present_authnx && that_present_authnx))
          return false;
        if (!this.authnx.equals(that.authnx))
          return false;
      }

      boolean this_present_authzx = true && this.isSetAuthzx();
      boolean that_present_authzx = true && that.isSetAuthzx();
      if (this_present_authzx || that_present_authzx) {
        if (!(this_present_authzx && that_present_authzx))
          return false;
        if (!this.authzx.equals(that.authzx))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_authnx = true && (isSetAuthnx());
      builder.append(present_authnx);
      if (present_authnx)
        builder.append(authnx);

      boolean present_authzx = true && (isSetAuthzx());
      builder.append(present_authzx);
      if (present_authzx)
        builder.append(authzx);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetAuthnx()).compareTo(other.isSetAuthnx());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthnx()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authnx, other.authnx);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetAuthzx()).compareTo(other.isSetAuthzx());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAuthzx()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authzx, other.authzx);
        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("login_result(");
      boolean first = true;

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

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

    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 login_resultStandardSchemeFactory implements SchemeFactory {
      public login_resultStandardScheme getScheme() {
        return new login_resultStandardScheme();
      }
    }

    private static class login_resultStandardScheme extends StandardScheme<login_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, login_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: // AUTHNX
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authnx = new AuthenticationException();
                struct.authnx.read(iprot);
                struct.setAuthnxIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // AUTHZX
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.authzx = new AuthorizationException();
                struct.authzx.read(iprot);
                struct.setAuthzxIsSet(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, login_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.authnx != null) {
          oprot.writeFieldBegin(AUTHNX_FIELD_DESC);
          struct.authnx.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.authzx != null) {
          oprot.writeFieldBegin(AUTHZX_FIELD_DESC);
          struct.authzx.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class login_resultTupleSchemeFactory implements SchemeFactory {
      public login_resultTupleScheme getScheme() {
        return new login_resultTupleScheme();
      }
    }

    private static class login_resultTupleScheme extends TupleScheme<login_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, login_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetAuthnx()) {
          optionals.set(0);
        }
        if (struct.isSetAuthzx()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetAuthnx()) {
          struct.authnx.write(oprot);
        }
        if (struct.isSetAuthzx()) {
          struct.authzx.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, login_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.authnx = new AuthenticationException();
          struct.authnx.read(iprot);
          struct.setAuthnxIsSet(true);
        }
        if (incoming.get(1)) {
          struct.authzx = new AuthorizationException();
          struct.authzx.read(iprot);
          struct.setAuthzxIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEYSPACE_FIELD_DESC = new org.apache.thrift.protocol.TField("keyspace", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public String keyspace; // 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 {
      KEYSPACE((short)1, "keyspace");

      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: // KEYSPACE
            return KEYSPACE;
          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.KEYSPACE, new org.apache.thrift.meta_data.FieldMetaData("keyspace", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(set_keyspace_args.class, metaDataMap);
    }

    public set_keyspace_args() {
    }

    public set_keyspace_args(
      String keyspace)
    {
      this();
      this.keyspace = keyspace;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public set_keyspace_args(set_keyspace_args other) {
      if (other.isSetKeyspace()) {
        this.keyspace = other.keyspace;
      }
    }

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

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

    public String getKeyspace() {
      return this.keyspace;
    }

    public set_keyspace_args setKeyspace(String keyspace) {
      this.keyspace = keyspace;
      return this;
    }

    public void unsetKeyspace() {
      this.keyspace = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYSPACE:
        if (value == null) {
          unsetKeyspace();
        } else {
          setKeyspace((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYSPACE:
        return getKeyspace();

      }
      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 KEYSPACE:
        return isSetKeyspace();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_keyspace = true && this.isSetKeyspace();
      boolean that_present_keyspace = true && that.isSetKeyspace();
      if (this_present_keyspace || that_present_keyspace) {
        if (!(this_present_keyspace && that_present_keyspace))
          return false;
        if (!this.keyspace.equals(that.keyspace))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keyspace = true && (isSetKeyspace());
      builder.append(present_keyspace);
      if (present_keyspace)
        builder.append(keyspace);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeyspace()).compareTo(other.isSetKeyspace());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeyspace()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyspace, other.keyspace);
        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("set_keyspace_args(");
      boolean first = true;

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

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

    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 set_keyspace_argsStandardSchemeFactory implements SchemeFactory {
      public set_keyspace_argsStandardScheme getScheme() {
        return new set_keyspace_argsStandardScheme();
      }
    }

    private static class set_keyspace_argsStandardScheme extends StandardScheme<set_keyspace_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, set_keyspace_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: // KEYSPACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.keyspace = iprot.readString();
                struct.setKeyspaceIsSet(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, set_keyspace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keyspace != null) {
          oprot.writeFieldBegin(KEYSPACE_FIELD_DESC);
          oprot.writeString(struct.keyspace);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class set_keyspace_argsTupleSchemeFactory implements SchemeFactory {
      public set_keyspace_argsTupleScheme getScheme() {
        return new set_keyspace_argsTupleScheme();
      }
    }

    private static class set_keyspace_argsTupleScheme extends TupleScheme<set_keyspace_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, set_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.keyspace);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, set_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.keyspace = iprot.readString();
        struct.setKeyspaceIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 set_keyspace_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new set_keyspace_resultTupleSchemeFactory());
    }

    public InvalidRequestException ire; // 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 {
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(set_keyspace_result.class, metaDataMap);
    }

    public set_keyspace_result() {
    }

    public set_keyspace_result(
      InvalidRequestException ire)
    {
      this();
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public set_keyspace_result(set_keyspace_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

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

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

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public set_keyspace_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("set_keyspace_result(");
      boolean first = true;

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

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

    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 set_keyspace_resultStandardSchemeFactory implements SchemeFactory {
      public set_keyspace_resultStandardScheme getScheme() {
        return new set_keyspace_resultStandardScheme();
      }
    }

    private static class set_keyspace_resultStandardScheme extends StandardScheme<set_keyspace_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, set_keyspace_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, set_keyspace_result struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class set_keyspace_resultTupleSchemeFactory implements SchemeFactory {
      public set_keyspace_resultTupleScheme getScheme() {
        return new set_keyspace_resultTupleScheme();
      }
    }

    private static class set_keyspace_resultTupleScheme extends TupleScheme<set_keyspace_result> {

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

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

  }

  public static class get_args implements org.apache.thrift.TBase<get_args, get_args._Fields>, java.io.Serializable, Cloneable, Comparable<get_args>   {
    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 KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("column_path", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)3);

    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());
    }

    public ByteBuffer key; // required
    public ColumnPath column_path; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_PATH((short)2, "column_path"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)3, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_PATH
            return COLUMN_PATH;
          case 3: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_PATH, new org.apache.thrift.meta_data.FieldMetaData("column_path", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnPath.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_args.class, metaDataMap);
    }

    public get_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public get_args(
      ByteBuffer key,
      ColumnPath column_path,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.column_path = column_path;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_args(get_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_path()) {
        this.column_path = new ColumnPath(other.column_path);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_path = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public get_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public get_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnPath getColumn_path() {
      return this.column_path;
    }

    public get_args setColumn_path(ColumnPath column_path) {
      this.column_path = column_path;
      return this;
    }

    public void unsetColumn_path() {
      this.column_path = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public get_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_PATH:
        if (value == null) {
          unsetColumn_path();
        } else {
          setColumn_path((ColumnPath)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_PATH:
        return getColumn_path();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_PATH:
        return isSetColumn_path();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      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_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_path = true && this.isSetColumn_path();
      boolean that_present_column_path = true && that.isSetColumn_path();
      if (this_present_column_path || that_present_column_path) {
        if (!(this_present_column_path && that_present_column_path))
          return false;
        if (!this.column_path.equals(that.column_path))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_path = true && (isSetColumn_path());
      builder.append(present_column_path);
      if (present_column_path)
        builder.append(column_path);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_path()).compareTo(other.isSetColumn_path());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_path()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_path, other.column_path);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("key:");
      if (this.key == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.key, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("column_path:");
      if (this.column_path == null) {
        sb.append("null");
      } else {
        sb.append(this.column_path);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency_level:");
      if (this.consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency_level);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PATH
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_path = new ColumnPath();
                struct.column_path.read(iprot);
                struct.setColumn_pathIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_path != null) {
          oprot.writeFieldBegin(COLUMN_PATH_FIELD_DESC);
          struct.column_path.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          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.key);
        struct.column_path.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_path = new ColumnPath();
        struct.column_path.read(iprot);
        struct.setColumn_pathIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

  public static class get_result implements org.apache.thrift.TBase<get_result, get_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_result>   {
    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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField NFE_FIELD_DESC = new org.apache.thrift.protocol.TField("nfe", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    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 ColumnOrSuperColumn success; // required
    public InvalidRequestException ire; // required
    public NotFoundException nfe; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      NFE((short)2, "nfe"),
      UE((short)3, "ue"),
      TE((short)4, "te");

      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: // IRE
            return IRE;
          case 2: // NFE
            return NFE;
          case 3: // UE
            return UE;
          case 4: // TE
            return TE;
          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, ColumnOrSuperColumn.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.NFE, new org.apache.thrift.meta_data.FieldMetaData("nfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(
      ColumnOrSuperColumn success,
      InvalidRequestException ire,
      NotFoundException nfe,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.nfe = nfe;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_result(get_result other) {
      if (other.isSetSuccess()) {
        this.success = new ColumnOrSuperColumn(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetNfe()) {
        this.nfe = new NotFoundException(other.nfe);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.nfe = null;
      this.ue = null;
      this.te = null;
    }

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

    public get_result setSuccess(ColumnOrSuperColumn 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public get_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public NotFoundException getNfe() {
      return this.nfe;
    }

    public get_result setNfe(NotFoundException nfe) {
      this.nfe = nfe;
      return this;
    }

    public void unsetNfe() {
      this.nfe = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case NFE:
        if (value == null) {
          unsetNfe();
        } else {
          setNfe((NotFoundException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case NFE:
        return getNfe();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case NFE:
        return isSetNfe();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_nfe = true && this.isSetNfe();
      boolean that_present_nfe = true && that.isSetNfe();
      if (this_present_nfe || that_present_nfe) {
        if (!(this_present_nfe && that_present_nfe))
          return false;
        if (!this.nfe.equals(that.nfe))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_nfe = true && (isSetNfe());
      builder.append(present_nfe);
      if (present_nfe)
        builder.append(nfe);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetNfe()).compareTo(other.isSetNfe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNfe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nfe, other.nfe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("nfe:");
      if (this.nfe == null) {
        sb.append("null");
      } else {
        sb.append(this.nfe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 ColumnOrSuperColumn();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // NFE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.nfe = new NotFoundException();
                struct.nfe.read(iprot);
                struct.setNfeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.nfe != null) {
          oprot.writeFieldBegin(NFE_FIELD_DESC);
          struct.nfe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.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.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetNfe()) {
          optionals.set(2);
        }
        if (struct.isSetUe()) {
          optionals.set(3);
        }
        if (struct.isSetTe()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetNfe()) {
          struct.nfe.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.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(5);
        if (incoming.get(0)) {
          struct.success = new ColumnOrSuperColumn();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.nfe = new NotFoundException();
          struct.nfe.read(iprot);
          struct.setNfeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(4)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("predicate", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ByteBuffer key; // required
    public ColumnParent column_parent; // required
    public SlicePredicate predicate; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_PARENT((short)2, "column_parent"),
      PREDICATE((short)3, "predicate"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 3: // PREDICATE
            return PREDICATE;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_slice_args.class, metaDataMap);
    }

    public get_slice_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public get_slice_args(
      ByteBuffer key,
      ColumnParent column_parent,
      SlicePredicate predicate,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.column_parent = column_parent;
      this.predicate = predicate;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_slice_args(get_slice_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetPredicate()) {
        this.predicate = new SlicePredicate(other.predicate);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_parent = null;
      this.predicate = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public get_slice_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public get_slice_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public get_slice_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public SlicePredicate getPredicate() {
      return this.predicate;
    }

    public get_slice_args setPredicate(SlicePredicate predicate) {
      this.predicate = predicate;
      return this;
    }

    public void unsetPredicate() {
      this.predicate = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public get_slice_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case PREDICATE:
        if (value == null) {
          unsetPredicate();
        } else {
          setPredicate((SlicePredicate)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_PARENT:
        return getColumn_parent();

      case PREDICATE:
        return getPredicate();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_PARENT:
        return isSetColumn_parent();
      case PREDICATE:
        return isSetPredicate();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_predicate = true && this.isSetPredicate();
      boolean that_present_predicate = true && that.isSetPredicate();
      if (this_present_predicate || that_present_predicate) {
        if (!(this_present_predicate && that_present_predicate))
          return false;
        if (!this.predicate.equals(that.predicate))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_predicate = true && (isSetPredicate());
      builder.append(present_predicate);
      if (present_predicate)
        builder.append(predicate);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(other.isSetPredicate());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPredicate()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.predicate, other.predicate);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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_slice_args(");
      boolean first = true;

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

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (key == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
      }
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (predicate == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'predicate' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (predicate != null) {
        predicate.validate();
      }
    }

    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_slice_argsStandardSchemeFactory implements SchemeFactory {
      public get_slice_argsStandardScheme getScheme() {
        return new get_slice_argsStandardScheme();
      }
    }

    private static class get_slice_argsStandardScheme extends StandardScheme<get_slice_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_slice_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PREDICATE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.predicate = new SlicePredicate();
                struct.predicate.read(iprot);
                struct.setPredicateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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_slice_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.predicate != null) {
          oprot.writeFieldBegin(PREDICATE_FIELD_DESC);
          struct.predicate.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_slice_argsTupleSchemeFactory implements SchemeFactory {
      public get_slice_argsTupleScheme getScheme() {
        return new get_slice_argsTupleScheme();
      }
    }

    private static class get_slice_argsTupleScheme extends TupleScheme<get_slice_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        struct.column_parent.write(oprot);
        struct.predicate.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.predicate = new SlicePredicate();
        struct.predicate.read(iprot);
        struct.setPredicateIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

  public static class get_slice_result implements org.apache.thrift.TBase<get_slice_result, get_slice_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_slice_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_slice_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public List<ColumnOrSuperColumn> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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, ColumnOrSuperColumn.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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_slice_result.class, metaDataMap);
    }

    public get_slice_result() {
    }

    public get_slice_result(
      List<ColumnOrSuperColumn> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_slice_result(get_slice_result other) {
      if (other.isSetSuccess()) {
        List<ColumnOrSuperColumn> __this__success = new ArrayList<ColumnOrSuperColumn>(other.success.size());
        for (ColumnOrSuperColumn other_element : other.success) {
          __this__success.add(new ColumnOrSuperColumn(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

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

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

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

    public get_slice_result setSuccess(List<ColumnOrSuperColumn> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public get_slice_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_slice_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_slice_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(get_slice_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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_slice_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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_slice_resultStandardSchemeFactory implements SchemeFactory {
      public get_slice_resultStandardScheme getScheme() {
        return new get_slice_resultStandardScheme();
      }
    }

    private static class get_slice_resultStandardScheme extends StandardScheme<get_slice_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_slice_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 _list224 = iprot.readListBegin();
                  struct.success = new ArrayList<ColumnOrSuperColumn>(_list224.size);
                  for (int _i225 = 0; _i225 < _list224.size; ++_i225)
                  {
                    ColumnOrSuperColumn _elem226;
                    _elem226 = new ColumnOrSuperColumn();
                    _elem226.read(iprot);
                    struct.success.add(_elem226);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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_slice_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 (ColumnOrSuperColumn _iter227 : struct.success)
            {
              _iter227.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_slice_resultTupleSchemeFactory implements SchemeFactory {
      public get_slice_resultTupleScheme getScheme() {
        return new get_slice_resultTupleScheme();
      }
    }

    private static class get_slice_resultTupleScheme extends TupleScheme<get_slice_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (ColumnOrSuperColumn _iter228 : struct.success)
            {
              _iter228.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list229 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<ColumnOrSuperColumn>(_list229.size);
            for (int _i230 = 0; _i230 < _list229.size; ++_i230)
            {
              ColumnOrSuperColumn _elem231;
              _elem231 = new ColumnOrSuperColumn();
              _elem231.read(iprot);
              struct.success.add(_elem231);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("predicate", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ByteBuffer key; // required
    public ColumnParent column_parent; // required
    public SlicePredicate predicate; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_PARENT((short)2, "column_parent"),
      PREDICATE((short)3, "predicate"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 3: // PREDICATE
            return PREDICATE;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_count_args.class, metaDataMap);
    }

    public get_count_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public get_count_args(
      ByteBuffer key,
      ColumnParent column_parent,
      SlicePredicate predicate,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.column_parent = column_parent;
      this.predicate = predicate;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_count_args(get_count_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetPredicate()) {
        this.predicate = new SlicePredicate(other.predicate);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_parent = null;
      this.predicate = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public get_count_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public get_count_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public get_count_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public SlicePredicate getPredicate() {
      return this.predicate;
    }

    public get_count_args setPredicate(SlicePredicate predicate) {
      this.predicate = predicate;
      return this;
    }

    public void unsetPredicate() {
      this.predicate = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public get_count_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case PREDICATE:
        if (value == null) {
          unsetPredicate();
        } else {
          setPredicate((SlicePredicate)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_PARENT:
        return getColumn_parent();

      case PREDICATE:
        return getPredicate();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_PARENT:
        return isSetColumn_parent();
      case PREDICATE:
        return isSetPredicate();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_predicate = true && this.isSetPredicate();
      boolean that_present_predicate = true && that.isSetPredicate();
      if (this_present_predicate || that_present_predicate) {
        if (!(this_present_predicate && that_present_predicate))
          return false;
        if (!this.predicate.equals(that.predicate))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_predicate = true && (isSetPredicate());
      builder.append(present_predicate);
      if (present_predicate)
        builder.append(predicate);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(other.isSetPredicate());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPredicate()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.predicate, other.predicate);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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_count_args(");
      boolean first = true;

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

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (key == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
      }
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (predicate == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'predicate' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (predicate != null) {
        predicate.validate();
      }
    }

    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_count_argsStandardSchemeFactory implements SchemeFactory {
      public get_count_argsStandardScheme getScheme() {
        return new get_count_argsStandardScheme();
      }
    }

    private static class get_count_argsStandardScheme extends StandardScheme<get_count_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_count_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PREDICATE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.predicate = new SlicePredicate();
                struct.predicate.read(iprot);
                struct.setPredicateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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_count_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.predicate != null) {
          oprot.writeFieldBegin(PREDICATE_FIELD_DESC);
          struct.predicate.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_count_argsTupleSchemeFactory implements SchemeFactory {
      public get_count_argsTupleScheme getScheme() {
        return new get_count_argsTupleScheme();
      }
    }

    private static class get_count_argsTupleScheme extends TupleScheme<get_count_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_count_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        struct.column_parent.write(oprot);
        struct.predicate.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_count_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.predicate = new SlicePredicate();
        struct.predicate.read(iprot);
        struct.setPredicateIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

  public static class get_count_result implements org.apache.thrift.TBase<get_count_result, get_count_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_count_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_count_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public int success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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 byte __isset_bitfield = 0;
    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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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_count_result.class, metaDataMap);
    }

    public get_count_result() {
    }

    public get_count_result(
      int success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_count_result(get_count_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = 0;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

    public get_count_result setSuccess(int success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

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

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public get_count_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_count_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_count_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(get_count_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true;
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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_count_result(");
      boolean first = true;

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

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

    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_bitfield = 0;
        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_count_resultStandardSchemeFactory implements SchemeFactory {
      public get_count_resultStandardScheme getScheme() {
        return new get_count_resultStandardScheme();
      }
    }

    private static class get_count_resultStandardScheme extends StandardScheme<get_count_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_count_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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_count_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeI32(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_count_resultTupleSchemeFactory implements SchemeFactory {
      public get_count_resultTupleScheme getScheme() {
        return new get_count_resultTupleScheme();
      }
    }

    private static class get_count_resultTupleScheme extends TupleScheme<get_count_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_count_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          oprot.writeI32(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_count_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.success = iprot.readI32();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEYS_FIELD_DESC = new org.apache.thrift.protocol.TField("keys", org.apache.thrift.protocol.TType.LIST, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("predicate", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public List<ByteBuffer> keys; // required
    public ColumnParent column_parent; // required
    public SlicePredicate predicate; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEYS((short)1, "keys"),
      COLUMN_PARENT((short)2, "column_parent"),
      PREDICATE((short)3, "predicate"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEYS
            return KEYS;
          case 2: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 3: // PREDICATE
            return PREDICATE;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEYS, new org.apache.thrift.meta_data.FieldMetaData("keys", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(multiget_slice_args.class, metaDataMap);
    }

    public multiget_slice_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public multiget_slice_args(
      List<ByteBuffer> keys,
      ColumnParent column_parent,
      SlicePredicate predicate,
      ConsistencyLevel consistency_level)
    {
      this();
      this.keys = keys;
      this.column_parent = column_parent;
      this.predicate = predicate;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public multiget_slice_args(multiget_slice_args other) {
      if (other.isSetKeys()) {
        List<ByteBuffer> __this__keys = new ArrayList<ByteBuffer>(other.keys);
        this.keys = __this__keys;
      }
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetPredicate()) {
        this.predicate = new SlicePredicate(other.predicate);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.keys = null;
      this.column_parent = null;
      this.predicate = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

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

    public java.util.Iterator<ByteBuffer> getKeysIterator() {
      return (this.keys == null) ? null : this.keys.iterator();
    }

    public void addToKeys(ByteBuffer elem) {
      if (this.keys == null) {
        this.keys = new ArrayList<ByteBuffer>();
      }
      this.keys.add(elem);
    }

    public List<ByteBuffer> getKeys() {
      return this.keys;
    }

    public multiget_slice_args setKeys(List<ByteBuffer> keys) {
      this.keys = keys;
      return this;
    }

    public void unsetKeys() {
      this.keys = null;
    }

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

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

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public multiget_slice_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public SlicePredicate getPredicate() {
      return this.predicate;
    }

    public multiget_slice_args setPredicate(SlicePredicate predicate) {
      this.predicate = predicate;
      return this;
    }

    public void unsetPredicate() {
      this.predicate = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public multiget_slice_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYS:
        if (value == null) {
          unsetKeys();
        } else {
          setKeys((List<ByteBuffer>)value);
        }
        break;

      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case PREDICATE:
        if (value == null) {
          unsetPredicate();
        } else {
          setPredicate((SlicePredicate)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYS:
        return getKeys();

      case COLUMN_PARENT:
        return getColumn_parent();

      case PREDICATE:
        return getPredicate();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEYS:
        return isSetKeys();
      case COLUMN_PARENT:
        return isSetColumn_parent();
      case PREDICATE:
        return isSetPredicate();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_keys = true && this.isSetKeys();
      boolean that_present_keys = true && that.isSetKeys();
      if (this_present_keys || that_present_keys) {
        if (!(this_present_keys && that_present_keys))
          return false;
        if (!this.keys.equals(that.keys))
          return false;
      }

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_predicate = true && this.isSetPredicate();
      boolean that_present_predicate = true && that.isSetPredicate();
      if (this_present_predicate || that_present_predicate) {
        if (!(this_present_predicate && that_present_predicate))
          return false;
        if (!this.predicate.equals(that.predicate))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keys = true && (isSetKeys());
      builder.append(present_keys);
      if (present_keys)
        builder.append(keys);

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_predicate = true && (isSetPredicate());
      builder.append(present_predicate);
      if (present_predicate)
        builder.append(predicate);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeys()).compareTo(other.isSetKeys());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeys()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keys, other.keys);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(other.isSetPredicate());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPredicate()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.predicate, other.predicate);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("multiget_slice_args(");
      boolean first = true;

      sb.append("keys:");
      if (this.keys == null) {
        sb.append("null");
      } else {
        sb.append(this.keys);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("column_parent:");
      if (this.column_parent == null) {
        sb.append("null");
      } else {
        sb.append(this.column_parent);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("predicate:");
      if (this.predicate == null) {
        sb.append("null");
      } else {
        sb.append(this.predicate);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency_level:");
      if (this.consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency_level);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (keys == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'keys' was not present! Struct: " + toString());
      }
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (predicate == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'predicate' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (predicate != null) {
        predicate.validate();
      }
    }

    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 multiget_slice_argsStandardSchemeFactory implements SchemeFactory {
      public multiget_slice_argsStandardScheme getScheme() {
        return new multiget_slice_argsStandardScheme();
      }
    }

    private static class multiget_slice_argsStandardScheme extends StandardScheme<multiget_slice_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, multiget_slice_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: // KEYS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list232 = iprot.readListBegin();
                  struct.keys = new ArrayList<ByteBuffer>(_list232.size);
                  for (int _i233 = 0; _i233 < _list232.size; ++_i233)
                  {
                    ByteBuffer _elem234;
                    _elem234 = iprot.readBinary();
                    struct.keys.add(_elem234);
                  }
                  iprot.readListEnd();
                }
                struct.setKeysIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PREDICATE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.predicate = new SlicePredicate();
                struct.predicate.read(iprot);
                struct.setPredicateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, multiget_slice_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keys != null) {
          oprot.writeFieldBegin(KEYS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.keys.size()));
            for (ByteBuffer _iter235 : struct.keys)
            {
              oprot.writeBinary(_iter235);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.predicate != null) {
          oprot.writeFieldBegin(PREDICATE_FIELD_DESC);
          struct.predicate.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class multiget_slice_argsTupleSchemeFactory implements SchemeFactory {
      public multiget_slice_argsTupleScheme getScheme() {
        return new multiget_slice_argsTupleScheme();
      }
    }

    private static class multiget_slice_argsTupleScheme extends TupleScheme<multiget_slice_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, multiget_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        {
          oprot.writeI32(struct.keys.size());
          for (ByteBuffer _iter236 : struct.keys)
          {
            oprot.writeBinary(_iter236);
          }
        }
        struct.column_parent.write(oprot);
        struct.predicate.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, multiget_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        {
          org.apache.thrift.protocol.TList _list237 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.keys = new ArrayList<ByteBuffer>(_list237.size);
          for (int _i238 = 0; _i238 < _list237.size; ++_i238)
          {
            ByteBuffer _elem239;
            _elem239 = iprot.readBinary();
            struct.keys.add(_elem239);
          }
        }
        struct.setKeysIsSet(true);
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.predicate = new SlicePredicate();
        struct.predicate.read(iprot);
        struct.setPredicateIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public Map<ByteBuffer,List<ColumnOrSuperColumn>> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true), 
              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, ColumnOrSuperColumn.class)))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(multiget_slice_result.class, metaDataMap);
    }

    public multiget_slice_result() {
    }

    public multiget_slice_result(
      Map<ByteBuffer,List<ColumnOrSuperColumn>> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public multiget_slice_result(multiget_slice_result other) {
      if (other.isSetSuccess()) {
        Map<ByteBuffer,List<ColumnOrSuperColumn>> __this__success = new HashMap<ByteBuffer,List<ColumnOrSuperColumn>>(other.success.size());
        for (Map.Entry<ByteBuffer, List<ColumnOrSuperColumn>> other_element : other.success.entrySet()) {

          ByteBuffer other_element_key = other_element.getKey();
          List<ColumnOrSuperColumn> other_element_value = other_element.getValue();

          ByteBuffer __this__success_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
;

          List<ColumnOrSuperColumn> __this__success_copy_value = new ArrayList<ColumnOrSuperColumn>(other_element_value.size());
          for (ColumnOrSuperColumn other_element_value_element : other_element_value) {
            __this__success_copy_value.add(new ColumnOrSuperColumn(other_element_value_element));
          }

          __this__success.put(__this__success_copy_key, __this__success_copy_value);
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

    public void putToSuccess(ByteBuffer key, List<ColumnOrSuperColumn> val) {
      if (this.success == null) {
        this.success = new HashMap<ByteBuffer,List<ColumnOrSuperColumn>>();
      }
      this.success.put(key, val);
    }

    public Map<ByteBuffer,List<ColumnOrSuperColumn>> getSuccess() {
      return this.success;
    }

    public multiget_slice_result setSuccess(Map<ByteBuffer,List<ColumnOrSuperColumn>> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public multiget_slice_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public multiget_slice_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public multiget_slice_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(multiget_slice_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("multiget_slice_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 multiget_slice_resultStandardSchemeFactory implements SchemeFactory {
      public multiget_slice_resultStandardScheme getScheme() {
        return new multiget_slice_resultStandardScheme();
      }
    }

    private static class multiget_slice_resultStandardScheme extends StandardScheme<multiget_slice_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, multiget_slice_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.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map240 = iprot.readMapBegin();
                  struct.success = new HashMap<ByteBuffer,List<ColumnOrSuperColumn>>(2*_map240.size);
                  for (int _i241 = 0; _i241 < _map240.size; ++_i241)
                  {
                    ByteBuffer _key242;
                    List<ColumnOrSuperColumn> _val243;
                    _key242 = iprot.readBinary();
                    {
                      org.apache.thrift.protocol.TList _list244 = iprot.readListBegin();
                      _val243 = new ArrayList<ColumnOrSuperColumn>(_list244.size);
                      for (int _i245 = 0; _i245 < _list244.size; ++_i245)
                      {
                        ColumnOrSuperColumn _elem246;
                        _elem246 = new ColumnOrSuperColumn();
                        _elem246.read(iprot);
                        _val243.add(_elem246);
                      }
                      iprot.readListEnd();
                    }
                    struct.success.put(_key242, _val243);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, multiget_slice_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, struct.success.size()));
            for (Map.Entry<ByteBuffer, List<ColumnOrSuperColumn>> _iter247 : struct.success.entrySet())
            {
              oprot.writeBinary(_iter247.getKey());
              {
                oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, _iter247.getValue().size()));
                for (ColumnOrSuperColumn _iter248 : _iter247.getValue())
                {
                  _iter248.write(oprot);
                }
                oprot.writeListEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class multiget_slice_resultTupleSchemeFactory implements SchemeFactory {
      public multiget_slice_resultTupleScheme getScheme() {
        return new multiget_slice_resultTupleScheme();
      }
    }

    private static class multiget_slice_resultTupleScheme extends TupleScheme<multiget_slice_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, multiget_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<ByteBuffer, List<ColumnOrSuperColumn>> _iter249 : struct.success.entrySet())
            {
              oprot.writeBinary(_iter249.getKey());
              {
                oprot.writeI32(_iter249.getValue().size());
                for (ColumnOrSuperColumn _iter250 : _iter249.getValue())
                {
                  _iter250.write(oprot);
                }
              }
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, multiget_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map251 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
            struct.success = new HashMap<ByteBuffer,List<ColumnOrSuperColumn>>(2*_map251.size);
            for (int _i252 = 0; _i252 < _map251.size; ++_i252)
            {
              ByteBuffer _key253;
              List<ColumnOrSuperColumn> _val254;
              _key253 = iprot.readBinary();
              {
                org.apache.thrift.protocol.TList _list255 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
                _val254 = new ArrayList<ColumnOrSuperColumn>(_list255.size);
                for (int _i256 = 0; _i256 < _list255.size; ++_i256)
                {
                  ColumnOrSuperColumn _elem257;
                  _elem257 = new ColumnOrSuperColumn();
                  _elem257.read(iprot);
                  _val254.add(_elem257);
                }
              }
              struct.success.put(_key253, _val254);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEYS_FIELD_DESC = new org.apache.thrift.protocol.TField("keys", org.apache.thrift.protocol.TType.LIST, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("predicate", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public List<ByteBuffer> keys; // required
    public ColumnParent column_parent; // required
    public SlicePredicate predicate; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEYS((short)1, "keys"),
      COLUMN_PARENT((short)2, "column_parent"),
      PREDICATE((short)3, "predicate"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEYS
            return KEYS;
          case 2: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 3: // PREDICATE
            return PREDICATE;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEYS, new org.apache.thrift.meta_data.FieldMetaData("keys", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(multiget_count_args.class, metaDataMap);
    }

    public multiget_count_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public multiget_count_args(
      List<ByteBuffer> keys,
      ColumnParent column_parent,
      SlicePredicate predicate,
      ConsistencyLevel consistency_level)
    {
      this();
      this.keys = keys;
      this.column_parent = column_parent;
      this.predicate = predicate;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public multiget_count_args(multiget_count_args other) {
      if (other.isSetKeys()) {
        List<ByteBuffer> __this__keys = new ArrayList<ByteBuffer>(other.keys);
        this.keys = __this__keys;
      }
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetPredicate()) {
        this.predicate = new SlicePredicate(other.predicate);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.keys = null;
      this.column_parent = null;
      this.predicate = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

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

    public java.util.Iterator<ByteBuffer> getKeysIterator() {
      return (this.keys == null) ? null : this.keys.iterator();
    }

    public void addToKeys(ByteBuffer elem) {
      if (this.keys == null) {
        this.keys = new ArrayList<ByteBuffer>();
      }
      this.keys.add(elem);
    }

    public List<ByteBuffer> getKeys() {
      return this.keys;
    }

    public multiget_count_args setKeys(List<ByteBuffer> keys) {
      this.keys = keys;
      return this;
    }

    public void unsetKeys() {
      this.keys = null;
    }

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

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

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public multiget_count_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public SlicePredicate getPredicate() {
      return this.predicate;
    }

    public multiget_count_args setPredicate(SlicePredicate predicate) {
      this.predicate = predicate;
      return this;
    }

    public void unsetPredicate() {
      this.predicate = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public multiget_count_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYS:
        if (value == null) {
          unsetKeys();
        } else {
          setKeys((List<ByteBuffer>)value);
        }
        break;

      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case PREDICATE:
        if (value == null) {
          unsetPredicate();
        } else {
          setPredicate((SlicePredicate)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYS:
        return getKeys();

      case COLUMN_PARENT:
        return getColumn_parent();

      case PREDICATE:
        return getPredicate();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEYS:
        return isSetKeys();
      case COLUMN_PARENT:
        return isSetColumn_parent();
      case PREDICATE:
        return isSetPredicate();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_keys = true && this.isSetKeys();
      boolean that_present_keys = true && that.isSetKeys();
      if (this_present_keys || that_present_keys) {
        if (!(this_present_keys && that_present_keys))
          return false;
        if (!this.keys.equals(that.keys))
          return false;
      }

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_predicate = true && this.isSetPredicate();
      boolean that_present_predicate = true && that.isSetPredicate();
      if (this_present_predicate || that_present_predicate) {
        if (!(this_present_predicate && that_present_predicate))
          return false;
        if (!this.predicate.equals(that.predicate))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keys = true && (isSetKeys());
      builder.append(present_keys);
      if (present_keys)
        builder.append(keys);

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_predicate = true && (isSetPredicate());
      builder.append(present_predicate);
      if (present_predicate)
        builder.append(predicate);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeys()).compareTo(other.isSetKeys());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeys()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keys, other.keys);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(other.isSetPredicate());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPredicate()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.predicate, other.predicate);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("multiget_count_args(");
      boolean first = true;

      sb.append("keys:");
      if (this.keys == null) {
        sb.append("null");
      } else {
        sb.append(this.keys);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("column_parent:");
      if (this.column_parent == null) {
        sb.append("null");
      } else {
        sb.append(this.column_parent);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("predicate:");
      if (this.predicate == null) {
        sb.append("null");
      } else {
        sb.append(this.predicate);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency_level:");
      if (this.consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency_level);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (keys == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'keys' was not present! Struct: " + toString());
      }
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (predicate == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'predicate' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (predicate != null) {
        predicate.validate();
      }
    }

    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 multiget_count_argsStandardSchemeFactory implements SchemeFactory {
      public multiget_count_argsStandardScheme getScheme() {
        return new multiget_count_argsStandardScheme();
      }
    }

    private static class multiget_count_argsStandardScheme extends StandardScheme<multiget_count_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, multiget_count_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: // KEYS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list258 = iprot.readListBegin();
                  struct.keys = new ArrayList<ByteBuffer>(_list258.size);
                  for (int _i259 = 0; _i259 < _list258.size; ++_i259)
                  {
                    ByteBuffer _elem260;
                    _elem260 = iprot.readBinary();
                    struct.keys.add(_elem260);
                  }
                  iprot.readListEnd();
                }
                struct.setKeysIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PREDICATE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.predicate = new SlicePredicate();
                struct.predicate.read(iprot);
                struct.setPredicateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, multiget_count_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keys != null) {
          oprot.writeFieldBegin(KEYS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.keys.size()));
            for (ByteBuffer _iter261 : struct.keys)
            {
              oprot.writeBinary(_iter261);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.predicate != null) {
          oprot.writeFieldBegin(PREDICATE_FIELD_DESC);
          struct.predicate.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class multiget_count_argsTupleSchemeFactory implements SchemeFactory {
      public multiget_count_argsTupleScheme getScheme() {
        return new multiget_count_argsTupleScheme();
      }
    }

    private static class multiget_count_argsTupleScheme extends TupleScheme<multiget_count_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, multiget_count_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        {
          oprot.writeI32(struct.keys.size());
          for (ByteBuffer _iter262 : struct.keys)
          {
            oprot.writeBinary(_iter262);
          }
        }
        struct.column_parent.write(oprot);
        struct.predicate.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, multiget_count_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        {
          org.apache.thrift.protocol.TList _list263 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.keys = new ArrayList<ByteBuffer>(_list263.size);
          for (int _i264 = 0; _i264 < _list263.size; ++_i264)
          {
            ByteBuffer _elem265;
            _elem265 = iprot.readBinary();
            struct.keys.add(_elem265);
          }
        }
        struct.setKeysIsSet(true);
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.predicate = new SlicePredicate();
        struct.predicate.read(iprot);
        struct.setPredicateIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public Map<ByteBuffer,Integer> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(multiget_count_result.class, metaDataMap);
    }

    public multiget_count_result() {
    }

    public multiget_count_result(
      Map<ByteBuffer,Integer> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public multiget_count_result(multiget_count_result other) {
      if (other.isSetSuccess()) {
        Map<ByteBuffer,Integer> __this__success = new HashMap<ByteBuffer,Integer>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

    public void putToSuccess(ByteBuffer key, int val) {
      if (this.success == null) {
        this.success = new HashMap<ByteBuffer,Integer>();
      }
      this.success.put(key, val);
    }

    public Map<ByteBuffer,Integer> getSuccess() {
      return this.success;
    }

    public multiget_count_result setSuccess(Map<ByteBuffer,Integer> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public multiget_count_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public multiget_count_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public multiget_count_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(multiget_count_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("multiget_count_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 multiget_count_resultStandardSchemeFactory implements SchemeFactory {
      public multiget_count_resultStandardScheme getScheme() {
        return new multiget_count_resultStandardScheme();
      }
    }

    private static class multiget_count_resultStandardScheme extends StandardScheme<multiget_count_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, multiget_count_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.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map266 = iprot.readMapBegin();
                  struct.success = new HashMap<ByteBuffer,Integer>(2*_map266.size);
                  for (int _i267 = 0; _i267 < _map266.size; ++_i267)
                  {
                    ByteBuffer _key268;
                    int _val269;
                    _key268 = iprot.readBinary();
                    _val269 = iprot.readI32();
                    struct.success.put(_key268, _val269);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, multiget_count_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.success.size()));
            for (Map.Entry<ByteBuffer, Integer> _iter270 : struct.success.entrySet())
            {
              oprot.writeBinary(_iter270.getKey());
              oprot.writeI32(_iter270.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class multiget_count_resultTupleSchemeFactory implements SchemeFactory {
      public multiget_count_resultTupleScheme getScheme() {
        return new multiget_count_resultTupleScheme();
      }
    }

    private static class multiget_count_resultTupleScheme extends TupleScheme<multiget_count_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, multiget_count_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<ByteBuffer, Integer> _iter271 : struct.success.entrySet())
            {
              oprot.writeBinary(_iter271.getKey());
              oprot.writeI32(_iter271.getValue());
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, multiget_count_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map272 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
            struct.success = new HashMap<ByteBuffer,Integer>(2*_map272.size);
            for (int _i273 = 0; _i273 < _map272.size; ++_i273)
            {
              ByteBuffer _key274;
              int _val275;
              _key274 = iprot.readBinary();
              _val275 = iprot.readI32();
              struct.success.put(_key274, _val275);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("predicate", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField RANGE_FIELD_DESC = new org.apache.thrift.protocol.TField("range", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ColumnParent column_parent; // required
    public SlicePredicate predicate; // required
    public KeyRange range; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      COLUMN_PARENT((short)1, "column_parent"),
      PREDICATE((short)2, "predicate"),
      RANGE((short)3, "range"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 2: // PREDICATE
            return PREDICATE;
          case 3: // RANGE
            return RANGE;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
      tmpMap.put(_Fields.RANGE, new org.apache.thrift.meta_data.FieldMetaData("range", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyRange.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_range_slices_args.class, metaDataMap);
    }

    public get_range_slices_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public get_range_slices_args(
      ColumnParent column_parent,
      SlicePredicate predicate,
      KeyRange range,
      ConsistencyLevel consistency_level)
    {
      this();
      this.column_parent = column_parent;
      this.predicate = predicate;
      this.range = range;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_range_slices_args(get_range_slices_args other) {
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetPredicate()) {
        this.predicate = new SlicePredicate(other.predicate);
      }
      if (other.isSetRange()) {
        this.range = new KeyRange(other.range);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.column_parent = null;
      this.predicate = null;
      this.range = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public get_range_slices_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public SlicePredicate getPredicate() {
      return this.predicate;
    }

    public get_range_slices_args setPredicate(SlicePredicate predicate) {
      this.predicate = predicate;
      return this;
    }

    public void unsetPredicate() {
      this.predicate = null;
    }

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

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

    public KeyRange getRange() {
      return this.range;
    }

    public get_range_slices_args setRange(KeyRange range) {
      this.range = range;
      return this;
    }

    public void unsetRange() {
      this.range = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public get_range_slices_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case PREDICATE:
        if (value == null) {
          unsetPredicate();
        } else {
          setPredicate((SlicePredicate)value);
        }
        break;

      case RANGE:
        if (value == null) {
          unsetRange();
        } else {
          setRange((KeyRange)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case COLUMN_PARENT:
        return getColumn_parent();

      case PREDICATE:
        return getPredicate();

      case RANGE:
        return getRange();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 COLUMN_PARENT:
        return isSetColumn_parent();
      case PREDICATE:
        return isSetPredicate();
      case RANGE:
        return isSetRange();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_predicate = true && this.isSetPredicate();
      boolean that_present_predicate = true && that.isSetPredicate();
      if (this_present_predicate || that_present_predicate) {
        if (!(this_present_predicate && that_present_predicate))
          return false;
        if (!this.predicate.equals(that.predicate))
          return false;
      }

      boolean this_present_range = true && this.isSetRange();
      boolean that_present_range = true && that.isSetRange();
      if (this_present_range || that_present_range) {
        if (!(this_present_range && that_present_range))
          return false;
        if (!this.range.equals(that.range))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_predicate = true && (isSetPredicate());
      builder.append(present_predicate);
      if (present_predicate)
        builder.append(predicate);

      boolean present_range = true && (isSetRange());
      builder.append(present_range);
      if (present_range)
        builder.append(range);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(other.isSetPredicate());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPredicate()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.predicate, other.predicate);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRange()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.range, other.range);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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_range_slices_args(");
      boolean first = true;

      sb.append("column_parent:");
      if (this.column_parent == null) {
        sb.append("null");
      } else {
        sb.append(this.column_parent);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("predicate:");
      if (this.predicate == null) {
        sb.append("null");
      } else {
        sb.append(this.predicate);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("range:");
      if (this.range == null) {
        sb.append("null");
      } else {
        sb.append(this.range);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency_level:");
      if (this.consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency_level);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (predicate == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'predicate' was not present! Struct: " + toString());
      }
      if (range == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'range' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (predicate != null) {
        predicate.validate();
      }
      if (range != null) {
        range.validate();
      }
    }

    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_range_slices_argsStandardSchemeFactory implements SchemeFactory {
      public get_range_slices_argsStandardScheme getScheme() {
        return new get_range_slices_argsStandardScheme();
      }
    }

    private static class get_range_slices_argsStandardScheme extends StandardScheme<get_range_slices_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_range_slices_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: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PREDICATE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.predicate = new SlicePredicate();
                struct.predicate.read(iprot);
                struct.setPredicateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // RANGE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.range = new KeyRange();
                struct.range.read(iprot);
                struct.setRangeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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_range_slices_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.predicate != null) {
          oprot.writeFieldBegin(PREDICATE_FIELD_DESC);
          struct.predicate.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.range != null) {
          oprot.writeFieldBegin(RANGE_FIELD_DESC);
          struct.range.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_range_slices_argsTupleSchemeFactory implements SchemeFactory {
      public get_range_slices_argsTupleScheme getScheme() {
        return new get_range_slices_argsTupleScheme();
      }
    }

    private static class get_range_slices_argsTupleScheme extends TupleScheme<get_range_slices_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_range_slices_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.column_parent.write(oprot);
        struct.predicate.write(oprot);
        struct.range.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_range_slices_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.predicate = new SlicePredicate();
        struct.predicate.read(iprot);
        struct.setPredicateIsSet(true);
        struct.range = new KeyRange();
        struct.range.read(iprot);
        struct.setRangeIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

  public static class get_range_slices_result implements org.apache.thrift.TBase<get_range_slices_result, get_range_slices_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_range_slices_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_range_slices_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public List<KeySlice> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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, KeySlice.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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_range_slices_result.class, metaDataMap);
    }

    public get_range_slices_result() {
    }

    public get_range_slices_result(
      List<KeySlice> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_range_slices_result(get_range_slices_result other) {
      if (other.isSetSuccess()) {
        List<KeySlice> __this__success = new ArrayList<KeySlice>(other.success.size());
        for (KeySlice other_element : other.success) {
          __this__success.add(new KeySlice(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

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

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

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

    public get_range_slices_result setSuccess(List<KeySlice> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public get_range_slices_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_range_slices_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_range_slices_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(get_range_slices_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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_range_slices_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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_range_slices_resultStandardSchemeFactory implements SchemeFactory {
      public get_range_slices_resultStandardScheme getScheme() {
        return new get_range_slices_resultStandardScheme();
      }
    }

    private static class get_range_slices_resultStandardScheme extends StandardScheme<get_range_slices_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_range_slices_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 _list276 = iprot.readListBegin();
                  struct.success = new ArrayList<KeySlice>(_list276.size);
                  for (int _i277 = 0; _i277 < _list276.size; ++_i277)
                  {
                    KeySlice _elem278;
                    _elem278 = new KeySlice();
                    _elem278.read(iprot);
                    struct.success.add(_elem278);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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_range_slices_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 (KeySlice _iter279 : struct.success)
            {
              _iter279.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_range_slices_resultTupleSchemeFactory implements SchemeFactory {
      public get_range_slices_resultTupleScheme getScheme() {
        return new get_range_slices_resultTupleScheme();
      }
    }

    private static class get_range_slices_resultTupleScheme extends TupleScheme<get_range_slices_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_range_slices_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (KeySlice _iter280 : struct.success)
            {
              _iter280.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_range_slices_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list281 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<KeySlice>(_list281.size);
            for (int _i282 = 0; _i282 < _list281.size; ++_i282)
            {
              KeySlice _elem283;
              _elem283 = new KeySlice();
              _elem283.read(iprot);
              struct.success.add(_elem283);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField COLUMN_FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("column_family", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField RANGE_FIELD_DESC = new org.apache.thrift.protocol.TField("range", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField START_COLUMN_FIELD_DESC = new org.apache.thrift.protocol.TField("start_column", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public String column_family; // required
    public KeyRange range; // required
    public ByteBuffer start_column; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      COLUMN_FAMILY((short)1, "column_family"),
      RANGE((short)2, "range"),
      START_COLUMN((short)3, "start_column"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // COLUMN_FAMILY
            return COLUMN_FAMILY;
          case 2: // RANGE
            return RANGE;
          case 3: // START_COLUMN
            return START_COLUMN;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.COLUMN_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("column_family", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.RANGE, new org.apache.thrift.meta_data.FieldMetaData("range", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyRange.class)));
      tmpMap.put(_Fields.START_COLUMN, new org.apache.thrift.meta_data.FieldMetaData("start_column", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_paged_slice_args.class, metaDataMap);
    }

    public get_paged_slice_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public get_paged_slice_args(
      String column_family,
      KeyRange range,
      ByteBuffer start_column,
      ConsistencyLevel consistency_level)
    {
      this();
      this.column_family = column_family;
      this.range = range;
      this.start_column = start_column;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_paged_slice_args(get_paged_slice_args other) {
      if (other.isSetColumn_family()) {
        this.column_family = other.column_family;
      }
      if (other.isSetRange()) {
        this.range = new KeyRange(other.range);
      }
      if (other.isSetStart_column()) {
        this.start_column = org.apache.thrift.TBaseHelper.copyBinary(other.start_column);
;
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.column_family = null;
      this.range = null;
      this.start_column = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public String getColumn_family() {
      return this.column_family;
    }

    public get_paged_slice_args setColumn_family(String column_family) {
      this.column_family = column_family;
      return this;
    }

    public void unsetColumn_family() {
      this.column_family = null;
    }

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

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

    public KeyRange getRange() {
      return this.range;
    }

    public get_paged_slice_args setRange(KeyRange range) {
      this.range = range;
      return this;
    }

    public void unsetRange() {
      this.range = null;
    }

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

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

    public byte[] getStart_column() {
      setStart_column(org.apache.thrift.TBaseHelper.rightSize(start_column));
      return start_column == null ? null : start_column.array();
    }

    public ByteBuffer bufferForStart_column() {
      return start_column;
    }

    public get_paged_slice_args setStart_column(byte[] start_column) {
      setStart_column(start_column == null ? (ByteBuffer)null : ByteBuffer.wrap(start_column));
      return this;
    }

    public get_paged_slice_args setStart_column(ByteBuffer start_column) {
      this.start_column = start_column;
      return this;
    }

    public void unsetStart_column() {
      this.start_column = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public get_paged_slice_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case COLUMN_FAMILY:
        if (value == null) {
          unsetColumn_family();
        } else {
          setColumn_family((String)value);
        }
        break;

      case RANGE:
        if (value == null) {
          unsetRange();
        } else {
          setRange((KeyRange)value);
        }
        break;

      case START_COLUMN:
        if (value == null) {
          unsetStart_column();
        } else {
          setStart_column((ByteBuffer)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case COLUMN_FAMILY:
        return getColumn_family();

      case RANGE:
        return getRange();

      case START_COLUMN:
        return getStart_column();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 COLUMN_FAMILY:
        return isSetColumn_family();
      case RANGE:
        return isSetRange();
      case START_COLUMN:
        return isSetStart_column();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_column_family = true && this.isSetColumn_family();
      boolean that_present_column_family = true && that.isSetColumn_family();
      if (this_present_column_family || that_present_column_family) {
        if (!(this_present_column_family && that_present_column_family))
          return false;
        if (!this.column_family.equals(that.column_family))
          return false;
      }

      boolean this_present_range = true && this.isSetRange();
      boolean that_present_range = true && that.isSetRange();
      if (this_present_range || that_present_range) {
        if (!(this_present_range && that_present_range))
          return false;
        if (!this.range.equals(that.range))
          return false;
      }

      boolean this_present_start_column = true && this.isSetStart_column();
      boolean that_present_start_column = true && that.isSetStart_column();
      if (this_present_start_column || that_present_start_column) {
        if (!(this_present_start_column && that_present_start_column))
          return false;
        if (!this.start_column.equals(that.start_column))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_column_family = true && (isSetColumn_family());
      builder.append(present_column_family);
      if (present_column_family)
        builder.append(column_family);

      boolean present_range = true && (isSetRange());
      builder.append(present_range);
      if (present_range)
        builder.append(range);

      boolean present_start_column = true && (isSetStart_column());
      builder.append(present_start_column);
      if (present_start_column)
        builder.append(start_column);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetColumn_family()).compareTo(other.isSetColumn_family());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_family()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_family, other.column_family);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRange()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.range, other.range);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetStart_column()).compareTo(other.isSetStart_column());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStart_column()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.start_column, other.start_column);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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_paged_slice_args(");
      boolean first = true;

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

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (column_family == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_family' was not present! Struct: " + toString());
      }
      if (range == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'range' was not present! Struct: " + toString());
      }
      if (start_column == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'start_column' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (range != null) {
        range.validate();
      }
    }

    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_paged_slice_argsStandardSchemeFactory implements SchemeFactory {
      public get_paged_slice_argsStandardScheme getScheme() {
        return new get_paged_slice_argsStandardScheme();
      }
    }

    private static class get_paged_slice_argsStandardScheme extends StandardScheme<get_paged_slice_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_paged_slice_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: // COLUMN_FAMILY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.column_family = iprot.readString();
                struct.setColumn_familyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // RANGE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.range = new KeyRange();
                struct.range.read(iprot);
                struct.setRangeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // START_COLUMN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.start_column = iprot.readBinary();
                struct.setStart_columnIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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_paged_slice_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.column_family != null) {
          oprot.writeFieldBegin(COLUMN_FAMILY_FIELD_DESC);
          oprot.writeString(struct.column_family);
          oprot.writeFieldEnd();
        }
        if (struct.range != null) {
          oprot.writeFieldBegin(RANGE_FIELD_DESC);
          struct.range.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.start_column != null) {
          oprot.writeFieldBegin(START_COLUMN_FIELD_DESC);
          oprot.writeBinary(struct.start_column);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_paged_slice_argsTupleSchemeFactory implements SchemeFactory {
      public get_paged_slice_argsTupleScheme getScheme() {
        return new get_paged_slice_argsTupleScheme();
      }
    }

    private static class get_paged_slice_argsTupleScheme extends TupleScheme<get_paged_slice_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_paged_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.column_family);
        struct.range.write(oprot);
        oprot.writeBinary(struct.start_column);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_paged_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.column_family = iprot.readString();
        struct.setColumn_familyIsSet(true);
        struct.range = new KeyRange();
        struct.range.read(iprot);
        struct.setRangeIsSet(true);
        struct.start_column = iprot.readBinary();
        struct.setStart_columnIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

  public static class get_paged_slice_result implements org.apache.thrift.TBase<get_paged_slice_result, get_paged_slice_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_paged_slice_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_paged_slice_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public List<KeySlice> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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, KeySlice.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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_paged_slice_result.class, metaDataMap);
    }

    public get_paged_slice_result() {
    }

    public get_paged_slice_result(
      List<KeySlice> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_paged_slice_result(get_paged_slice_result other) {
      if (other.isSetSuccess()) {
        List<KeySlice> __this__success = new ArrayList<KeySlice>(other.success.size());
        for (KeySlice other_element : other.success) {
          __this__success.add(new KeySlice(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

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

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

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

    public get_paged_slice_result setSuccess(List<KeySlice> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public get_paged_slice_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_paged_slice_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_paged_slice_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(get_paged_slice_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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_paged_slice_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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_paged_slice_resultStandardSchemeFactory implements SchemeFactory {
      public get_paged_slice_resultStandardScheme getScheme() {
        return new get_paged_slice_resultStandardScheme();
      }
    }

    private static class get_paged_slice_resultStandardScheme extends StandardScheme<get_paged_slice_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_paged_slice_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 _list284 = iprot.readListBegin();
                  struct.success = new ArrayList<KeySlice>(_list284.size);
                  for (int _i285 = 0; _i285 < _list284.size; ++_i285)
                  {
                    KeySlice _elem286;
                    _elem286 = new KeySlice();
                    _elem286.read(iprot);
                    struct.success.add(_elem286);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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_paged_slice_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 (KeySlice _iter287 : struct.success)
            {
              _iter287.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_paged_slice_resultTupleSchemeFactory implements SchemeFactory {
      public get_paged_slice_resultTupleScheme getScheme() {
        return new get_paged_slice_resultTupleScheme();
      }
    }

    private static class get_paged_slice_resultTupleScheme extends TupleScheme<get_paged_slice_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_paged_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (KeySlice _iter288 : struct.success)
            {
              _iter288.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_paged_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list289 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<KeySlice>(_list289.size);
            for (int _i290 = 0; _i290 < _list289.size; ++_i290)
            {
              KeySlice _elem291;
              _elem291 = new KeySlice();
              _elem291.read(iprot);
              struct.success.add(_elem291);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField INDEX_CLAUSE_FIELD_DESC = new org.apache.thrift.protocol.TField("index_clause", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField COLUMN_PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("column_predicate", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ColumnParent column_parent; // required
    public IndexClause index_clause; // required
    public SlicePredicate column_predicate; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      COLUMN_PARENT((short)1, "column_parent"),
      INDEX_CLAUSE((short)2, "index_clause"),
      COLUMN_PREDICATE((short)3, "column_predicate"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 2: // INDEX_CLAUSE
            return INDEX_CLAUSE;
          case 3: // COLUMN_PREDICATE
            return COLUMN_PREDICATE;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.INDEX_CLAUSE, new org.apache.thrift.meta_data.FieldMetaData("index_clause", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IndexClause.class)));
      tmpMap.put(_Fields.COLUMN_PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("column_predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_indexed_slices_args.class, metaDataMap);
    }

    public get_indexed_slices_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public get_indexed_slices_args(
      ColumnParent column_parent,
      IndexClause index_clause,
      SlicePredicate column_predicate,
      ConsistencyLevel consistency_level)
    {
      this();
      this.column_parent = column_parent;
      this.index_clause = index_clause;
      this.column_predicate = column_predicate;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_indexed_slices_args(get_indexed_slices_args other) {
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetIndex_clause()) {
        this.index_clause = new IndexClause(other.index_clause);
      }
      if (other.isSetColumn_predicate()) {
        this.column_predicate = new SlicePredicate(other.column_predicate);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.column_parent = null;
      this.index_clause = null;
      this.column_predicate = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public get_indexed_slices_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public IndexClause getIndex_clause() {
      return this.index_clause;
    }

    public get_indexed_slices_args setIndex_clause(IndexClause index_clause) {
      this.index_clause = index_clause;
      return this;
    }

    public void unsetIndex_clause() {
      this.index_clause = null;
    }

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

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

    public SlicePredicate getColumn_predicate() {
      return this.column_predicate;
    }

    public get_indexed_slices_args setColumn_predicate(SlicePredicate column_predicate) {
      this.column_predicate = column_predicate;
      return this;
    }

    public void unsetColumn_predicate() {
      this.column_predicate = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public get_indexed_slices_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case INDEX_CLAUSE:
        if (value == null) {
          unsetIndex_clause();
        } else {
          setIndex_clause((IndexClause)value);
        }
        break;

      case COLUMN_PREDICATE:
        if (value == null) {
          unsetColumn_predicate();
        } else {
          setColumn_predicate((SlicePredicate)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case COLUMN_PARENT:
        return getColumn_parent();

      case INDEX_CLAUSE:
        return getIndex_clause();

      case COLUMN_PREDICATE:
        return getColumn_predicate();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 COLUMN_PARENT:
        return isSetColumn_parent();
      case INDEX_CLAUSE:
        return isSetIndex_clause();
      case COLUMN_PREDICATE:
        return isSetColumn_predicate();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_index_clause = true && this.isSetIndex_clause();
      boolean that_present_index_clause = true && that.isSetIndex_clause();
      if (this_present_index_clause || that_present_index_clause) {
        if (!(this_present_index_clause && that_present_index_clause))
          return false;
        if (!this.index_clause.equals(that.index_clause))
          return false;
      }

      boolean this_present_column_predicate = true && this.isSetColumn_predicate();
      boolean that_present_column_predicate = true && that.isSetColumn_predicate();
      if (this_present_column_predicate || that_present_column_predicate) {
        if (!(this_present_column_predicate && that_present_column_predicate))
          return false;
        if (!this.column_predicate.equals(that.column_predicate))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_index_clause = true && (isSetIndex_clause());
      builder.append(present_index_clause);
      if (present_index_clause)
        builder.append(index_clause);

      boolean present_column_predicate = true && (isSetColumn_predicate());
      builder.append(present_column_predicate);
      if (present_column_predicate)
        builder.append(column_predicate);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIndex_clause()).compareTo(other.isSetIndex_clause());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIndex_clause()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.index_clause, other.index_clause);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_predicate()).compareTo(other.isSetColumn_predicate());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_predicate()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_predicate, other.column_predicate);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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_indexed_slices_args(");
      boolean first = true;

      sb.append("column_parent:");
      if (this.column_parent == null) {
        sb.append("null");
      } else {
        sb.append(this.column_parent);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("index_clause:");
      if (this.index_clause == null) {
        sb.append("null");
      } else {
        sb.append(this.index_clause);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("column_predicate:");
      if (this.column_predicate == null) {
        sb.append("null");
      } else {
        sb.append(this.column_predicate);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency_level:");
      if (this.consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency_level);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (index_clause == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'index_clause' was not present! Struct: " + toString());
      }
      if (column_predicate == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_predicate' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (index_clause != null) {
        index_clause.validate();
      }
      if (column_predicate != null) {
        column_predicate.validate();
      }
    }

    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_indexed_slices_argsStandardSchemeFactory implements SchemeFactory {
      public get_indexed_slices_argsStandardScheme getScheme() {
        return new get_indexed_slices_argsStandardScheme();
      }
    }

    private static class get_indexed_slices_argsStandardScheme extends StandardScheme<get_indexed_slices_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_indexed_slices_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: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // INDEX_CLAUSE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.index_clause = new IndexClause();
                struct.index_clause.read(iprot);
                struct.setIndex_clauseIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // COLUMN_PREDICATE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_predicate = new SlicePredicate();
                struct.column_predicate.read(iprot);
                struct.setColumn_predicateIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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_indexed_slices_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.index_clause != null) {
          oprot.writeFieldBegin(INDEX_CLAUSE_FIELD_DESC);
          struct.index_clause.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.column_predicate != null) {
          oprot.writeFieldBegin(COLUMN_PREDICATE_FIELD_DESC);
          struct.column_predicate.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_indexed_slices_argsTupleSchemeFactory implements SchemeFactory {
      public get_indexed_slices_argsTupleScheme getScheme() {
        return new get_indexed_slices_argsTupleScheme();
      }
    }

    private static class get_indexed_slices_argsTupleScheme extends TupleScheme<get_indexed_slices_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_indexed_slices_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.column_parent.write(oprot);
        struct.index_clause.write(oprot);
        struct.column_predicate.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_indexed_slices_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.index_clause = new IndexClause();
        struct.index_clause.read(iprot);
        struct.setIndex_clauseIsSet(true);
        struct.column_predicate = new SlicePredicate();
        struct.column_predicate.read(iprot);
        struct.setColumn_predicateIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

  public static class get_indexed_slices_result implements org.apache.thrift.TBase<get_indexed_slices_result, get_indexed_slices_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_indexed_slices_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_indexed_slices_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public List<KeySlice> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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, KeySlice.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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_indexed_slices_result.class, metaDataMap);
    }

    public get_indexed_slices_result() {
    }

    public get_indexed_slices_result(
      List<KeySlice> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_indexed_slices_result(get_indexed_slices_result other) {
      if (other.isSetSuccess()) {
        List<KeySlice> __this__success = new ArrayList<KeySlice>(other.success.size());
        for (KeySlice other_element : other.success) {
          __this__success.add(new KeySlice(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

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

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

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

    public get_indexed_slices_result setSuccess(List<KeySlice> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public get_indexed_slices_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_indexed_slices_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_indexed_slices_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(get_indexed_slices_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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_indexed_slices_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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_indexed_slices_resultStandardSchemeFactory implements SchemeFactory {
      public get_indexed_slices_resultStandardScheme getScheme() {
        return new get_indexed_slices_resultStandardScheme();
      }
    }

    private static class get_indexed_slices_resultStandardScheme extends StandardScheme<get_indexed_slices_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_indexed_slices_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 _list292 = iprot.readListBegin();
                  struct.success = new ArrayList<KeySlice>(_list292.size);
                  for (int _i293 = 0; _i293 < _list292.size; ++_i293)
                  {
                    KeySlice _elem294;
                    _elem294 = new KeySlice();
                    _elem294.read(iprot);
                    struct.success.add(_elem294);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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_indexed_slices_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 (KeySlice _iter295 : struct.success)
            {
              _iter295.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_indexed_slices_resultTupleSchemeFactory implements SchemeFactory {
      public get_indexed_slices_resultTupleScheme getScheme() {
        return new get_indexed_slices_resultTupleScheme();
      }
    }

    private static class get_indexed_slices_resultTupleScheme extends TupleScheme<get_indexed_slices_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_indexed_slices_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (KeySlice _iter296 : struct.success)
            {
              _iter296.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_indexed_slices_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list297 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<KeySlice>(_list297.size);
            for (int _i298 = 0; _i298 < _list297.size; ++_i298)
            {
              KeySlice _elem299;
              _elem299 = new KeySlice();
              _elem299.read(iprot);
              struct.success.add(_elem299);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField COLUMN_FIELD_DESC = new org.apache.thrift.protocol.TField("column", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ByteBuffer key; // required
    public ColumnParent column_parent; // required
    public Column column; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_PARENT((short)2, "column_parent"),
      COLUMN((short)3, "column"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 3: // COLUMN
            return COLUMN;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.COLUMN, new org.apache.thrift.meta_data.FieldMetaData("column", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Column.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(insert_args.class, metaDataMap);
    }

    public insert_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public insert_args(
      ByteBuffer key,
      ColumnParent column_parent,
      Column column,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.column_parent = column_parent;
      this.column = column;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public insert_args(insert_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetColumn()) {
        this.column = new Column(other.column);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_parent = null;
      this.column = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public insert_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public insert_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public insert_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public Column getColumn() {
      return this.column;
    }

    public insert_args setColumn(Column column) {
      this.column = column;
      return this;
    }

    public void unsetColumn() {
      this.column = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public insert_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case COLUMN:
        if (value == null) {
          unsetColumn();
        } else {
          setColumn((Column)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_PARENT:
        return getColumn_parent();

      case COLUMN:
        return getColumn();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_PARENT:
        return isSetColumn_parent();
      case COLUMN:
        return isSetColumn();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_column = true && this.isSetColumn();
      boolean that_present_column = true && that.isSetColumn();
      if (this_present_column || that_present_column) {
        if (!(this_present_column && that_present_column))
          return false;
        if (!this.column.equals(that.column))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_column = true && (isSetColumn());
      builder.append(present_column);
      if (present_column)
        builder.append(column);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn()).compareTo(other.isSetColumn());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column, other.column);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("insert_args(");
      boolean first = true;

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

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (key == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
      }
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (column == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (column != null) {
        column.validate();
      }
    }

    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 insert_argsStandardSchemeFactory implements SchemeFactory {
      public insert_argsStandardScheme getScheme() {
        return new insert_argsStandardScheme();
      }
    }

    private static class insert_argsStandardScheme extends StandardScheme<insert_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, insert_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // COLUMN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column = new Column();
                struct.column.read(iprot);
                struct.setColumnIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, insert_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.column != null) {
          oprot.writeFieldBegin(COLUMN_FIELD_DESC);
          struct.column.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class insert_argsTupleSchemeFactory implements SchemeFactory {
      public insert_argsTupleScheme getScheme() {
        return new insert_argsTupleScheme();
      }
    }

    private static class insert_argsTupleScheme extends TupleScheme<insert_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, insert_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        struct.column_parent.write(oprot);
        struct.column.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, insert_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.column = new Column();
        struct.column.read(iprot);
        struct.setColumnIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(insert_result.class, metaDataMap);
    }

    public insert_result() {
    }

    public insert_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public insert_result(insert_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public insert_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public insert_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public insert_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("insert_result(");
      boolean first = true;

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

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

    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 insert_resultStandardSchemeFactory implements SchemeFactory {
      public insert_resultStandardScheme getScheme() {
        return new insert_resultStandardScheme();
      }
    }

    private static class insert_resultStandardScheme extends StandardScheme<insert_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, insert_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, insert_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class insert_resultTupleSchemeFactory implements SchemeFactory {
      public insert_resultTupleScheme getScheme() {
        return new insert_resultTupleScheme();
      }
    }

    private static class insert_resultTupleScheme extends TupleScheme<insert_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, insert_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, insert_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField COLUMN_FIELD_DESC = new org.apache.thrift.protocol.TField("column", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ByteBuffer key; // required
    public ColumnParent column_parent; // required
    public CounterColumn column; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_PARENT((short)2, "column_parent"),
      COLUMN((short)3, "column"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_PARENT
            return COLUMN_PARENT;
          case 3: // COLUMN
            return COLUMN;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
      tmpMap.put(_Fields.COLUMN, new org.apache.thrift.meta_data.FieldMetaData("column", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CounterColumn.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(add_args.class, metaDataMap);
    }

    public add_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public add_args(
      ByteBuffer key,
      ColumnParent column_parent,
      CounterColumn column,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.column_parent = column_parent;
      this.column = column;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public add_args(add_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_parent()) {
        this.column_parent = new ColumnParent(other.column_parent);
      }
      if (other.isSetColumn()) {
        this.column = new CounterColumn(other.column);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_parent = null;
      this.column = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public add_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public add_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnParent getColumn_parent() {
      return this.column_parent;
    }

    public add_args setColumn_parent(ColumnParent column_parent) {
      this.column_parent = column_parent;
      return this;
    }

    public void unsetColumn_parent() {
      this.column_parent = null;
    }

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

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

    public CounterColumn getColumn() {
      return this.column;
    }

    public add_args setColumn(CounterColumn column) {
      this.column = column;
      return this;
    }

    public void unsetColumn() {
      this.column = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public add_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_PARENT:
        if (value == null) {
          unsetColumn_parent();
        } else {
          setColumn_parent((ColumnParent)value);
        }
        break;

      case COLUMN:
        if (value == null) {
          unsetColumn();
        } else {
          setColumn((CounterColumn)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_PARENT:
        return getColumn_parent();

      case COLUMN:
        return getColumn();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_PARENT:
        return isSetColumn_parent();
      case COLUMN:
        return isSetColumn();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_parent = true && this.isSetColumn_parent();
      boolean that_present_column_parent = true && that.isSetColumn_parent();
      if (this_present_column_parent || that_present_column_parent) {
        if (!(this_present_column_parent && that_present_column_parent))
          return false;
        if (!this.column_parent.equals(that.column_parent))
          return false;
      }

      boolean this_present_column = true && this.isSetColumn();
      boolean that_present_column = true && that.isSetColumn();
      if (this_present_column || that_present_column) {
        if (!(this_present_column && that_present_column))
          return false;
        if (!this.column.equals(that.column))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_parent = true && (isSetColumn_parent());
      builder.append(present_column_parent);
      if (present_column_parent)
        builder.append(column_parent);

      boolean present_column = true && (isSetColumn());
      builder.append(present_column);
      if (present_column)
        builder.append(column);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(other.isSetColumn_parent());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_parent()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, other.column_parent);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn()).compareTo(other.isSetColumn());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column, other.column);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("add_args(");
      boolean first = true;

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

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (key == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
      }
      if (column_parent == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
      }
      if (column == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column' was not present! Struct: " + toString());
      }
      if (consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (column_parent != null) {
        column_parent.validate();
      }
      if (column != null) {
        column.validate();
      }
    }

    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 add_argsStandardSchemeFactory implements SchemeFactory {
      public add_argsStandardScheme getScheme() {
        return new add_argsStandardScheme();
      }
    }

    private static class add_argsStandardScheme extends StandardScheme<add_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, add_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PARENT
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_parent = new ColumnParent();
                struct.column_parent.read(iprot);
                struct.setColumn_parentIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // COLUMN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column = new CounterColumn();
                struct.column.read(iprot);
                struct.setColumnIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, add_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_parent != null) {
          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
          struct.column_parent.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.column != null) {
          oprot.writeFieldBegin(COLUMN_FIELD_DESC);
          struct.column.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class add_argsTupleSchemeFactory implements SchemeFactory {
      public add_argsTupleScheme getScheme() {
        return new add_argsTupleScheme();
      }
    }

    private static class add_argsTupleScheme extends TupleScheme<add_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, add_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        struct.column_parent.write(oprot);
        struct.column.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, add_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_parent = new ColumnParent();
        struct.column_parent.read(iprot);
        struct.setColumn_parentIsSet(true);
        struct.column = new CounterColumn();
        struct.column.read(iprot);
        struct.setColumnIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(add_result.class, metaDataMap);
    }

    public add_result() {
    }

    public add_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public add_result(add_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public add_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public add_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public add_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("add_result(");
      boolean first = true;

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

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

    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 add_resultStandardSchemeFactory implements SchemeFactory {
      public add_resultStandardScheme getScheme() {
        return new add_resultStandardScheme();
      }
    }

    private static class add_resultStandardScheme extends StandardScheme<add_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, add_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, add_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class add_resultTupleSchemeFactory implements SchemeFactory {
      public add_resultTupleScheme getScheme() {
        return new add_resultTupleScheme();
      }
    }

    private static class add_resultTupleScheme extends TupleScheme<add_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, add_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, add_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("column_family", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField EXPECTED_FIELD_DESC = new org.apache.thrift.protocol.TField("expected", org.apache.thrift.protocol.TType.LIST, (short)3);
    private static final org.apache.thrift.protocol.TField UPDATES_FIELD_DESC = new org.apache.thrift.protocol.TField("updates", org.apache.thrift.protocol.TType.LIST, (short)4);
    private static final org.apache.thrift.protocol.TField SERIAL_CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("serial_consistency_level", org.apache.thrift.protocol.TType.I32, (short)5);
    private static final org.apache.thrift.protocol.TField COMMIT_CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("commit_consistency_level", org.apache.thrift.protocol.TType.I32, (short)6);

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

    public ByteBuffer key; // required
    public String column_family; // required
    public List<Column> expected; // required
    public List<Column> updates; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel serial_consistency_level; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel commit_consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_FAMILY((short)2, "column_family"),
      EXPECTED((short)3, "expected"),
      UPDATES((short)4, "updates"),
      /**
       * 
       * @see ConsistencyLevel
       */
      SERIAL_CONSISTENCY_LEVEL((short)5, "serial_consistency_level"),
      /**
       * 
       * @see ConsistencyLevel
       */
      COMMIT_CONSISTENCY_LEVEL((short)6, "commit_consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_FAMILY
            return COLUMN_FAMILY;
          case 3: // EXPECTED
            return EXPECTED;
          case 4: // UPDATES
            return UPDATES;
          case 5: // SERIAL_CONSISTENCY_LEVEL
            return SERIAL_CONSISTENCY_LEVEL;
          case 6: // COMMIT_CONSISTENCY_LEVEL
            return COMMIT_CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("column_family", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.EXPECTED, new org.apache.thrift.meta_data.FieldMetaData("expected", 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, Column.class))));
      tmpMap.put(_Fields.UPDATES, new org.apache.thrift.meta_data.FieldMetaData("updates", 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, Column.class))));
      tmpMap.put(_Fields.SERIAL_CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("serial_consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      tmpMap.put(_Fields.COMMIT_CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("commit_consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cas_args.class, metaDataMap);
    }

    public cas_args() {
      this.serial_consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.SERIAL;

      this.commit_consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.QUORUM;

    }

    public cas_args(
      ByteBuffer key,
      String column_family,
      List<Column> expected,
      List<Column> updates,
      ConsistencyLevel serial_consistency_level,
      ConsistencyLevel commit_consistency_level)
    {
      this();
      this.key = key;
      this.column_family = column_family;
      this.expected = expected;
      this.updates = updates;
      this.serial_consistency_level = serial_consistency_level;
      this.commit_consistency_level = commit_consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cas_args(cas_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_family()) {
        this.column_family = other.column_family;
      }
      if (other.isSetExpected()) {
        List<Column> __this__expected = new ArrayList<Column>(other.expected.size());
        for (Column other_element : other.expected) {
          __this__expected.add(new Column(other_element));
        }
        this.expected = __this__expected;
      }
      if (other.isSetUpdates()) {
        List<Column> __this__updates = new ArrayList<Column>(other.updates.size());
        for (Column other_element : other.updates) {
          __this__updates.add(new Column(other_element));
        }
        this.updates = __this__updates;
      }
      if (other.isSetSerial_consistency_level()) {
        this.serial_consistency_level = other.serial_consistency_level;
      }
      if (other.isSetCommit_consistency_level()) {
        this.commit_consistency_level = other.commit_consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_family = null;
      this.expected = null;
      this.updates = null;
      this.serial_consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.SERIAL;

      this.commit_consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.QUORUM;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public cas_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public cas_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public String getColumn_family() {
      return this.column_family;
    }

    public cas_args setColumn_family(String column_family) {
      this.column_family = column_family;
      return this;
    }

    public void unsetColumn_family() {
      this.column_family = null;
    }

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

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

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

    public java.util.Iterator<Column> getExpectedIterator() {
      return (this.expected == null) ? null : this.expected.iterator();
    }

    public void addToExpected(Column elem) {
      if (this.expected == null) {
        this.expected = new ArrayList<Column>();
      }
      this.expected.add(elem);
    }

    public List<Column> getExpected() {
      return this.expected;
    }

    public cas_args setExpected(List<Column> expected) {
      this.expected = expected;
      return this;
    }

    public void unsetExpected() {
      this.expected = null;
    }

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

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

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

    public java.util.Iterator<Column> getUpdatesIterator() {
      return (this.updates == null) ? null : this.updates.iterator();
    }

    public void addToUpdates(Column elem) {
      if (this.updates == null) {
        this.updates = new ArrayList<Column>();
      }
      this.updates.add(elem);
    }

    public List<Column> getUpdates() {
      return this.updates;
    }

    public cas_args setUpdates(List<Column> updates) {
      this.updates = updates;
      return this;
    }

    public void unsetUpdates() {
      this.updates = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getSerial_consistency_level() {
      return this.serial_consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public cas_args setSerial_consistency_level(ConsistencyLevel serial_consistency_level) {
      this.serial_consistency_level = serial_consistency_level;
      return this;
    }

    public void unsetSerial_consistency_level() {
      this.serial_consistency_level = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getCommit_consistency_level() {
      return this.commit_consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public cas_args setCommit_consistency_level(ConsistencyLevel commit_consistency_level) {
      this.commit_consistency_level = commit_consistency_level;
      return this;
    }

    public void unsetCommit_consistency_level() {
      this.commit_consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_FAMILY:
        if (value == null) {
          unsetColumn_family();
        } else {
          setColumn_family((String)value);
        }
        break;

      case EXPECTED:
        if (value == null) {
          unsetExpected();
        } else {
          setExpected((List<Column>)value);
        }
        break;

      case UPDATES:
        if (value == null) {
          unsetUpdates();
        } else {
          setUpdates((List<Column>)value);
        }
        break;

      case SERIAL_CONSISTENCY_LEVEL:
        if (value == null) {
          unsetSerial_consistency_level();
        } else {
          setSerial_consistency_level((ConsistencyLevel)value);
        }
        break;

      case COMMIT_CONSISTENCY_LEVEL:
        if (value == null) {
          unsetCommit_consistency_level();
        } else {
          setCommit_consistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_FAMILY:
        return getColumn_family();

      case EXPECTED:
        return getExpected();

      case UPDATES:
        return getUpdates();

      case SERIAL_CONSISTENCY_LEVEL:
        return getSerial_consistency_level();

      case COMMIT_CONSISTENCY_LEVEL:
        return getCommit_consistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_FAMILY:
        return isSetColumn_family();
      case EXPECTED:
        return isSetExpected();
      case UPDATES:
        return isSetUpdates();
      case SERIAL_CONSISTENCY_LEVEL:
        return isSetSerial_consistency_level();
      case COMMIT_CONSISTENCY_LEVEL:
        return isSetCommit_consistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_family = true && this.isSetColumn_family();
      boolean that_present_column_family = true && that.isSetColumn_family();
      if (this_present_column_family || that_present_column_family) {
        if (!(this_present_column_family && that_present_column_family))
          return false;
        if (!this.column_family.equals(that.column_family))
          return false;
      }

      boolean this_present_expected = true && this.isSetExpected();
      boolean that_present_expected = true && that.isSetExpected();
      if (this_present_expected || that_present_expected) {
        if (!(this_present_expected && that_present_expected))
          return false;
        if (!this.expected.equals(that.expected))
          return false;
      }

      boolean this_present_updates = true && this.isSetUpdates();
      boolean that_present_updates = true && that.isSetUpdates();
      if (this_present_updates || that_present_updates) {
        if (!(this_present_updates && that_present_updates))
          return false;
        if (!this.updates.equals(that.updates))
          return false;
      }

      boolean this_present_serial_consistency_level = true && this.isSetSerial_consistency_level();
      boolean that_present_serial_consistency_level = true && that.isSetSerial_consistency_level();
      if (this_present_serial_consistency_level || that_present_serial_consistency_level) {
        if (!(this_present_serial_consistency_level && that_present_serial_consistency_level))
          return false;
        if (!this.serial_consistency_level.equals(that.serial_consistency_level))
          return false;
      }

      boolean this_present_commit_consistency_level = true && this.isSetCommit_consistency_level();
      boolean that_present_commit_consistency_level = true && that.isSetCommit_consistency_level();
      if (this_present_commit_consistency_level || that_present_commit_consistency_level) {
        if (!(this_present_commit_consistency_level && that_present_commit_consistency_level))
          return false;
        if (!this.commit_consistency_level.equals(that.commit_consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_family = true && (isSetColumn_family());
      builder.append(present_column_family);
      if (present_column_family)
        builder.append(column_family);

      boolean present_expected = true && (isSetExpected());
      builder.append(present_expected);
      if (present_expected)
        builder.append(expected);

      boolean present_updates = true && (isSetUpdates());
      builder.append(present_updates);
      if (present_updates)
        builder.append(updates);

      boolean present_serial_consistency_level = true && (isSetSerial_consistency_level());
      builder.append(present_serial_consistency_level);
      if (present_serial_consistency_level)
        builder.append(serial_consistency_level.getValue());

      boolean present_commit_consistency_level = true && (isSetCommit_consistency_level());
      builder.append(present_commit_consistency_level);
      if (present_commit_consistency_level)
        builder.append(commit_consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_family()).compareTo(other.isSetColumn_family());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_family()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_family, other.column_family);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetExpected()).compareTo(other.isSetExpected());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetExpected()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.expected, other.expected);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUpdates()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updates, other.updates);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSerial_consistency_level()).compareTo(other.isSetSerial_consistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSerial_consistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.serial_consistency_level, other.serial_consistency_level);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetCommit_consistency_level()).compareTo(other.isSetCommit_consistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCommit_consistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.commit_consistency_level, other.commit_consistency_level);
        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("cas_args(");
      boolean first = true;

      sb.append("key:");
      if (this.key == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.key, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("column_family:");
      if (this.column_family == null) {
        sb.append("null");
      } else {
        sb.append(this.column_family);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("expected:");
      if (this.expected == null) {
        sb.append("null");
      } else {
        sb.append(this.expected);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("updates:");
      if (this.updates == null) {
        sb.append("null");
      } else {
        sb.append(this.updates);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("serial_consistency_level:");
      if (this.serial_consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.serial_consistency_level);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("commit_consistency_level:");
      if (this.commit_consistency_level == null) {
        sb.append("null");
      } else {
        sb.append(this.commit_consistency_level);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (key == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
      }
      if (column_family == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_family' was not present! Struct: " + toString());
      }
      if (serial_consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'serial_consistency_level' was not present! Struct: " + toString());
      }
      if (commit_consistency_level == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'commit_consistency_level' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 cas_argsStandardSchemeFactory implements SchemeFactory {
      public cas_argsStandardScheme getScheme() {
        return new cas_argsStandardScheme();
      }
    }

    private static class cas_argsStandardScheme extends StandardScheme<cas_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, cas_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_FAMILY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.column_family = iprot.readString();
                struct.setColumn_familyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // EXPECTED
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list300 = iprot.readListBegin();
                  struct.expected = new ArrayList<Column>(_list300.size);
                  for (int _i301 = 0; _i301 < _list300.size; ++_i301)
                  {
                    Column _elem302;
                    _elem302 = new Column();
                    _elem302.read(iprot);
                    struct.expected.add(_elem302);
                  }
                  iprot.readListEnd();
                }
                struct.setExpectedIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // UPDATES
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list303 = iprot.readListBegin();
                  struct.updates = new ArrayList<Column>(_list303.size);
                  for (int _i304 = 0; _i304 < _list303.size; ++_i304)
                  {
                    Column _elem305;
                    _elem305 = new Column();
                    _elem305.read(iprot);
                    struct.updates.add(_elem305);
                  }
                  iprot.readListEnd();
                }
                struct.setUpdatesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // SERIAL_CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.serial_consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setSerial_consistency_levelIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 6: // COMMIT_CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.commit_consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setCommit_consistency_levelIsSet(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, cas_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_family != null) {
          oprot.writeFieldBegin(COLUMN_FAMILY_FIELD_DESC);
          oprot.writeString(struct.column_family);
          oprot.writeFieldEnd();
        }
        if (struct.expected != null) {
          oprot.writeFieldBegin(EXPECTED_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.expected.size()));
            for (Column _iter306 : struct.expected)
            {
              _iter306.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.updates != null) {
          oprot.writeFieldBegin(UPDATES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.updates.size()));
            for (Column _iter307 : struct.updates)
            {
              _iter307.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.serial_consistency_level != null) {
          oprot.writeFieldBegin(SERIAL_CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.serial_consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        if (struct.commit_consistency_level != null) {
          oprot.writeFieldBegin(COMMIT_CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.commit_consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class cas_argsTupleSchemeFactory implements SchemeFactory {
      public cas_argsTupleScheme getScheme() {
        return new cas_argsTupleScheme();
      }
    }

    private static class cas_argsTupleScheme extends TupleScheme<cas_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, cas_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        oprot.writeString(struct.column_family);
        oprot.writeI32(struct.serial_consistency_level.getValue());
        oprot.writeI32(struct.commit_consistency_level.getValue());
        BitSet optionals = new BitSet();
        if (struct.isSetExpected()) {
          optionals.set(0);
        }
        if (struct.isSetUpdates()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetExpected()) {
          {
            oprot.writeI32(struct.expected.size());
            for (Column _iter308 : struct.expected)
            {
              _iter308.write(oprot);
            }
          }
        }
        if (struct.isSetUpdates()) {
          {
            oprot.writeI32(struct.updates.size());
            for (Column _iter309 : struct.updates)
            {
              _iter309.write(oprot);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cas_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_family = iprot.readString();
        struct.setColumn_familyIsSet(true);
        struct.serial_consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setSerial_consistency_levelIsSet(true);
        struct.commit_consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setCommit_consistency_levelIsSet(true);
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list310 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.expected = new ArrayList<Column>(_list310.size);
            for (int _i311 = 0; _i311 < _list310.size; ++_i311)
            {
              Column _elem312;
              _elem312 = new Column();
              _elem312.read(iprot);
              struct.expected.add(_elem312);
            }
          }
          struct.setExpectedIsSet(true);
        }
        if (incoming.get(1)) {
          {
            org.apache.thrift.protocol.TList _list313 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.updates = new ArrayList<Column>(_list313.size);
            for (int _i314 = 0; _i314 < _list313.size; ++_i314)
            {
              Column _elem315;
              _elem315 = new Column();
              _elem315.read(iprot);
              struct.updates.add(_elem315);
            }
          }
          struct.setUpdatesIsSet(true);
        }
      }
    }

  }

  public static class cas_result implements org.apache.thrift.TBase<cas_result, cas_result._Fields>, java.io.Serializable, Cloneable, Comparable<cas_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("cas_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public CASResult success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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, CASResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(cas_result.class, metaDataMap);
    }

    public cas_result() {
    }

    public cas_result(
      CASResult success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public cas_result(cas_result other) {
      if (other.isSetSuccess()) {
        this.success = new CASResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

    public cas_result setSuccess(CASResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public cas_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public cas_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public cas_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(cas_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("cas_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 cas_resultStandardSchemeFactory implements SchemeFactory {
      public cas_resultStandardScheme getScheme() {
        return new cas_resultStandardScheme();
      }
    }

    private static class cas_resultStandardScheme extends StandardScheme<cas_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, cas_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 CASResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, cas_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class cas_resultTupleSchemeFactory implements SchemeFactory {
      public cas_resultTupleScheme getScheme() {
        return new cas_resultTupleScheme();
      }
    }

    private static class cas_resultTupleScheme extends TupleScheme<cas_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, cas_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, cas_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          struct.success = new CASResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COLUMN_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("column_path", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)3);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);

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

    public ByteBuffer key; // required
    public ColumnPath column_path; // required
    public long timestamp; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      COLUMN_PATH((short)2, "column_path"),
      TIMESTAMP((short)3, "timestamp"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)4, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // COLUMN_PATH
            return COLUMN_PATH;
          case 3: // TIMESTAMP
            return TIMESTAMP;
          case 4: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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 __TIMESTAMP_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COLUMN_PATH, new org.apache.thrift.meta_data.FieldMetaData("column_path", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnPath.class)));
      tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(remove_args.class, metaDataMap);
    }

    public remove_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public remove_args(
      ByteBuffer key,
      ColumnPath column_path,
      long timestamp,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.column_path = column_path;
      this.timestamp = timestamp;
      setTimestampIsSet(true);
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public remove_args(remove_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetColumn_path()) {
        this.column_path = new ColumnPath(other.column_path);
      }
      this.timestamp = other.timestamp;
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.column_path = null;
      setTimestampIsSet(false);
      this.timestamp = 0;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public remove_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public remove_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnPath getColumn_path() {
      return this.column_path;
    }

    public remove_args setColumn_path(ColumnPath column_path) {
      this.column_path = column_path;
      return this;
    }

    public void unsetColumn_path() {
      this.column_path = null;
    }

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

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

    public long getTimestamp() {
      return this.timestamp;
    }

    public remove_args setTimestamp(long timestamp) {
      this.timestamp = timestamp;
      setTimestampIsSet(true);
      return this;
    }

    public void unsetTimestamp() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
    }

    /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */
    public boolean isSetTimestamp() {
      return EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
    }

    public void setTimestampIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public remove_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case COLUMN_PATH:
        if (value == null) {
          unsetColumn_path();
        } else {
          setColumn_path((ColumnPath)value);
        }
        break;

      case TIMESTAMP:
        if (value == null) {
          unsetTimestamp();
        } else {
          setTimestamp((Long)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case COLUMN_PATH:
        return getColumn_path();

      case TIMESTAMP:
        return Long.valueOf(getTimestamp());

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case COLUMN_PATH:
        return isSetColumn_path();
      case TIMESTAMP:
        return isSetTimestamp();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_column_path = true && this.isSetColumn_path();
      boolean that_present_column_path = true && that.isSetColumn_path();
      if (this_present_column_path || that_present_column_path) {
        if (!(this_present_column_path && that_present_column_path))
          return false;
        if (!this.column_path.equals(that.column_path))
          return false;
      }

      boolean this_present_timestamp = true;
      boolean that_present_timestamp = true;
      if (this_present_timestamp || that_present_timestamp) {
        if (!(this_present_timestamp && that_present_timestamp))
          return false;
        if (this.timestamp != that.timestamp)
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_column_path = true && (isSetColumn_path());
      builder.append(present_column_path);
      if (present_column_path)
        builder.append(column_path);

      boolean present_timestamp = true;
      builder.append(present_timestamp);
      if (present_timestamp)
        builder.append(timestamp);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetColumn_path()).compareTo(other.isSetColumn_path());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_path()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_path, other.column_path);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTimestamp()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, other.timestamp);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("remove_args(");
      boolean first = true;

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

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (key == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
      }
      if (column_path == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_path' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'timestamp' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
      if (column_path != null) {
        column_path.validate();
      }
    }

    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_bitfield = 0;
        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 remove_argsStandardSchemeFactory implements SchemeFactory {
      public remove_argsStandardScheme getScheme() {
        return new remove_argsStandardScheme();
      }
    }

    private static class remove_argsStandardScheme extends StandardScheme<remove_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, remove_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COLUMN_PATH
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.column_path = new ColumnPath();
                struct.column_path.read(iprot);
                struct.setColumn_pathIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TIMESTAMP
              if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
                struct.timestamp = iprot.readI64();
                struct.setTimestampIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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.isSetTimestamp()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'timestamp' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.column_path != null) {
          oprot.writeFieldBegin(COLUMN_PATH_FIELD_DESC);
          struct.column_path.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
        oprot.writeI64(struct.timestamp);
        oprot.writeFieldEnd();
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class remove_argsTupleSchemeFactory implements SchemeFactory {
      public remove_argsTupleScheme getScheme() {
        return new remove_argsTupleScheme();
      }
    }

    private static class remove_argsTupleScheme extends TupleScheme<remove_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, remove_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        struct.column_path.write(oprot);
        oprot.writeI64(struct.timestamp);
        BitSet optionals = new BitSet();
        if (struct.isSetConsistency_level()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetConsistency_level()) {
          oprot.writeI32(struct.consistency_level.getValue());
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, remove_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.column_path = new ColumnPath();
        struct.column_path.read(iprot);
        struct.setColumn_pathIsSet(true);
        struct.timestamp = iprot.readI64();
        struct.setTimestampIsSet(true);
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
          struct.setConsistency_levelIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(remove_result.class, metaDataMap);
    }

    public remove_result() {
    }

    public remove_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public remove_result(remove_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public remove_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public remove_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public remove_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("remove_result(");
      boolean first = true;

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

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

    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 remove_resultStandardSchemeFactory implements SchemeFactory {
      public remove_resultStandardScheme getScheme() {
        return new remove_resultStandardScheme();
      }
    }

    private static class remove_resultStandardScheme extends StandardScheme<remove_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, remove_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, remove_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class remove_resultTupleSchemeFactory implements SchemeFactory {
      public remove_resultTupleScheme getScheme() {
        return new remove_resultTupleScheme();
      }
    }

    private static class remove_resultTupleScheme extends TupleScheme<remove_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, remove_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, remove_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("path", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)3);

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

    public ByteBuffer key; // required
    public ColumnPath path; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      KEY((short)1, "key"),
      PATH((short)2, "path"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)3, "consistency_level");

      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: // KEY
            return KEY;
          case 2: // PATH
            return PATH;
          case 3: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.PATH, new org.apache.thrift.meta_data.FieldMetaData("path", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnPath.class)));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(remove_counter_args.class, metaDataMap);
    }

    public remove_counter_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public remove_counter_args(
      ByteBuffer key,
      ColumnPath path,
      ConsistencyLevel consistency_level)
    {
      this();
      this.key = key;
      this.path = path;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public remove_counter_args(remove_counter_args other) {
      if (other.isSetKey()) {
        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
;
      }
      if (other.isSetPath()) {
        this.path = new ColumnPath(other.path);
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.key = null;
      this.path = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public byte[] getKey() {
      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
      return key == null ? null : key.array();
    }

    public ByteBuffer bufferForKey() {
      return key;
    }

    public remove_counter_args setKey(byte[] key) {
      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
      return this;
    }

    public remove_counter_args setKey(ByteBuffer key) {
      this.key = key;
      return this;
    }

    public void unsetKey() {
      this.key = null;
    }

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

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

    public ColumnPath getPath() {
      return this.path;
    }

    public remove_counter_args setPath(ColumnPath path) {
      this.path = path;
      return this;
    }

    public void unsetPath() {
      this.path = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public remove_counter_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEY:
        if (value == null) {
          unsetKey();
        } else {
          setKey((ByteBuffer)value);
        }
        break;

      case PATH:
        if (value == null) {
          unsetPath();
        } else {
          setPath((ColumnPath)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEY:
        return getKey();

      case PATH:
        return getPath();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 KEY:
        return isSetKey();
      case PATH:
        return isSetPath();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_key = true && this.isSetKey();
      boolean that_present_key = true && that.isSetKey();
      if (this_present_key || that_present_key) {
        if (!(this_present_key && that_present_key))
          return false;
        if (!this.key.equals(that.key))
          return false;
      }

      boolean this_present_path = true && this.isSetPath();
      boolean that_present_path = true && that.isSetPath();
      if (this_present_path || that_present_path) {
        if (!(this_present_path && that_present_path))
          return false;
        if (!this.path.equals(that.path))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_key = true && (isSetKey());
      builder.append(present_key);
      if (present_key)
        builder.append(key);

      boolean present_path = true && (isSetPath());
      builder.append(present_path);
      if (present_path)
        builder.append(path);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKey()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, other.key);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetPath()).compareTo(other.isSetPath());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPath()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.path, other.path);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("remove_counter_args(");
      boolean first = true;

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

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

    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 remove_counter_argsStandardSchemeFactory implements SchemeFactory {
      public remove_counter_argsStandardScheme getScheme() {
        return new remove_counter_argsStandardScheme();
      }
    }

    private static class remove_counter_argsStandardScheme extends StandardScheme<remove_counter_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, remove_counter_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: // KEY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.key = iprot.readBinary();
                struct.setKeyIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PATH
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.path = new ColumnPath();
                struct.path.read(iprot);
                struct.setPathIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, remove_counter_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.key != null) {
          oprot.writeFieldBegin(KEY_FIELD_DESC);
          oprot.writeBinary(struct.key);
          oprot.writeFieldEnd();
        }
        if (struct.path != null) {
          oprot.writeFieldBegin(PATH_FIELD_DESC);
          struct.path.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class remove_counter_argsTupleSchemeFactory implements SchemeFactory {
      public remove_counter_argsTupleScheme getScheme() {
        return new remove_counter_argsTupleScheme();
      }
    }

    private static class remove_counter_argsTupleScheme extends TupleScheme<remove_counter_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, remove_counter_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.key);
        struct.path.write(oprot);
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, remove_counter_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.key = iprot.readBinary();
        struct.setKeyIsSet(true);
        struct.path = new ColumnPath();
        struct.path.read(iprot);
        struct.setPathIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(remove_counter_result.class, metaDataMap);
    }

    public remove_counter_result() {
    }

    public remove_counter_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public remove_counter_result(remove_counter_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public remove_counter_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public remove_counter_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public remove_counter_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("remove_counter_result(");
      boolean first = true;

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

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

    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 remove_counter_resultStandardSchemeFactory implements SchemeFactory {
      public remove_counter_resultStandardScheme getScheme() {
        return new remove_counter_resultStandardScheme();
      }
    }

    private static class remove_counter_resultStandardScheme extends StandardScheme<remove_counter_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, remove_counter_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, remove_counter_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class remove_counter_resultTupleSchemeFactory implements SchemeFactory {
      public remove_counter_resultTupleScheme getScheme() {
        return new remove_counter_resultTupleScheme();
      }
    }

    private static class remove_counter_resultTupleScheme extends TupleScheme<remove_counter_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, remove_counter_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, remove_counter_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField MUTATION_MAP_FIELD_DESC = new org.apache.thrift.protocol.TField("mutation_map", org.apache.thrift.protocol.TType.MAP, (short)1);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", 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 batch_mutate_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new batch_mutate_argsTupleSchemeFactory());
    }

    public Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      MUTATION_MAP((short)1, "mutation_map"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)2, "consistency_level");

      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: // MUTATION_MAP
            return MUTATION_MAP;
          case 2: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.MUTATION_MAP, new org.apache.thrift.meta_data.FieldMetaData("mutation_map", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true), 
              new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
                  new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
                  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, Mutation.class))))));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(batch_mutate_args.class, metaDataMap);
    }

    public batch_mutate_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public batch_mutate_args(
      Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map,
      ConsistencyLevel consistency_level)
    {
      this();
      this.mutation_map = mutation_map;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public batch_mutate_args(batch_mutate_args other) {
      if (other.isSetMutation_map()) {
        Map<ByteBuffer,Map<String,List<Mutation>>> __this__mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>(other.mutation_map.size());
        for (Map.Entry<ByteBuffer, Map<String,List<Mutation>>> other_element : other.mutation_map.entrySet()) {

          ByteBuffer other_element_key = other_element.getKey();
          Map<String,List<Mutation>> other_element_value = other_element.getValue();

          ByteBuffer __this__mutation_map_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
;

          Map<String,List<Mutation>> __this__mutation_map_copy_value = new HashMap<String,List<Mutation>>(other_element_value.size());
          for (Map.Entry<String, List<Mutation>> other_element_value_element : other_element_value.entrySet()) {

            String other_element_value_element_key = other_element_value_element.getKey();
            List<Mutation> other_element_value_element_value = other_element_value_element.getValue();

            String __this__mutation_map_copy_value_copy_key = other_element_value_element_key;

            List<Mutation> __this__mutation_map_copy_value_copy_value = new ArrayList<Mutation>(other_element_value_element_value.size());
            for (Mutation other_element_value_element_value_element : other_element_value_element_value) {
              __this__mutation_map_copy_value_copy_value.add(new Mutation(other_element_value_element_value_element));
            }

            __this__mutation_map_copy_value.put(__this__mutation_map_copy_value_copy_key, __this__mutation_map_copy_value_copy_value);
          }

          __this__mutation_map.put(__this__mutation_map_copy_key, __this__mutation_map_copy_value);
        }
        this.mutation_map = __this__mutation_map;
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.mutation_map = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

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

    public void putToMutation_map(ByteBuffer key, Map<String,List<Mutation>> val) {
      if (this.mutation_map == null) {
        this.mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>();
      }
      this.mutation_map.put(key, val);
    }

    public Map<ByteBuffer,Map<String,List<Mutation>>> getMutation_map() {
      return this.mutation_map;
    }

    public batch_mutate_args setMutation_map(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map) {
      this.mutation_map = mutation_map;
      return this;
    }

    public void unsetMutation_map() {
      this.mutation_map = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public batch_mutate_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case MUTATION_MAP:
        if (value == null) {
          unsetMutation_map();
        } else {
          setMutation_map((Map<ByteBuffer,Map<String,List<Mutation>>>)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case MUTATION_MAP:
        return getMutation_map();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 MUTATION_MAP:
        return isSetMutation_map();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_mutation_map = true && this.isSetMutation_map();
      boolean that_present_mutation_map = true && that.isSetMutation_map();
      if (this_present_mutation_map || that_present_mutation_map) {
        if (!(this_present_mutation_map && that_present_mutation_map))
          return false;
        if (!this.mutation_map.equals(that.mutation_map))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_mutation_map = true && (isSetMutation_map());
      builder.append(present_mutation_map);
      if (present_mutation_map)
        builder.append(mutation_map);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetMutation_map()).compareTo(other.isSetMutation_map());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetMutation_map()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.mutation_map, other.mutation_map);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("batch_mutate_args(");
      boolean first = true;

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

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

    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 batch_mutate_argsStandardSchemeFactory implements SchemeFactory {
      public batch_mutate_argsStandardScheme getScheme() {
        return new batch_mutate_argsStandardScheme();
      }
    }

    private static class batch_mutate_argsStandardScheme extends StandardScheme<batch_mutate_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, batch_mutate_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: // MUTATION_MAP
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map316 = iprot.readMapBegin();
                  struct.mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>(2*_map316.size);
                  for (int _i317 = 0; _i317 < _map316.size; ++_i317)
                  {
                    ByteBuffer _key318;
                    Map<String,List<Mutation>> _val319;
                    _key318 = iprot.readBinary();
                    {
                      org.apache.thrift.protocol.TMap _map320 = iprot.readMapBegin();
                      _val319 = new HashMap<String,List<Mutation>>(2*_map320.size);
                      for (int _i321 = 0; _i321 < _map320.size; ++_i321)
                      {
                        String _key322;
                        List<Mutation> _val323;
                        _key322 = iprot.readString();
                        {
                          org.apache.thrift.protocol.TList _list324 = iprot.readListBegin();
                          _val323 = new ArrayList<Mutation>(_list324.size);
                          for (int _i325 = 0; _i325 < _list324.size; ++_i325)
                          {
                            Mutation _elem326;
                            _elem326 = new Mutation();
                            _elem326.read(iprot);
                            _val323.add(_elem326);
                          }
                          iprot.readListEnd();
                        }
                        _val319.put(_key322, _val323);
                      }
                      iprot.readMapEnd();
                    }
                    struct.mutation_map.put(_key318, _val319);
                  }
                  iprot.readMapEnd();
                }
                struct.setMutation_mapIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, batch_mutate_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.mutation_map != null) {
          oprot.writeFieldBegin(MUTATION_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.MAP, struct.mutation_map.size()));
            for (Map.Entry<ByteBuffer, Map<String,List<Mutation>>> _iter327 : struct.mutation_map.entrySet())
            {
              oprot.writeBinary(_iter327.getKey());
              {
                oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, _iter327.getValue().size()));
                for (Map.Entry<String, List<Mutation>> _iter328 : _iter327.getValue().entrySet())
                {
                  oprot.writeString(_iter328.getKey());
                  {
                    oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, _iter328.getValue().size()));
                    for (Mutation _iter329 : _iter328.getValue())
                    {
                      _iter329.write(oprot);
                    }
                    oprot.writeListEnd();
                  }
                }
                oprot.writeMapEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class batch_mutate_argsTupleSchemeFactory implements SchemeFactory {
      public batch_mutate_argsTupleScheme getScheme() {
        return new batch_mutate_argsTupleScheme();
      }
    }

    private static class batch_mutate_argsTupleScheme extends TupleScheme<batch_mutate_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, batch_mutate_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        {
          oprot.writeI32(struct.mutation_map.size());
          for (Map.Entry<ByteBuffer, Map<String,List<Mutation>>> _iter330 : struct.mutation_map.entrySet())
          {
            oprot.writeBinary(_iter330.getKey());
            {
              oprot.writeI32(_iter330.getValue().size());
              for (Map.Entry<String, List<Mutation>> _iter331 : _iter330.getValue().entrySet())
              {
                oprot.writeString(_iter331.getKey());
                {
                  oprot.writeI32(_iter331.getValue().size());
                  for (Mutation _iter332 : _iter331.getValue())
                  {
                    _iter332.write(oprot);
                  }
                }
              }
            }
          }
        }
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, batch_mutate_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        {
          org.apache.thrift.protocol.TMap _map333 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.MAP, iprot.readI32());
          struct.mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>(2*_map333.size);
          for (int _i334 = 0; _i334 < _map333.size; ++_i334)
          {
            ByteBuffer _key335;
            Map<String,List<Mutation>> _val336;
            _key335 = iprot.readBinary();
            {
              org.apache.thrift.protocol.TMap _map337 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
              _val336 = new HashMap<String,List<Mutation>>(2*_map337.size);
              for (int _i338 = 0; _i338 < _map337.size; ++_i338)
              {
                String _key339;
                List<Mutation> _val340;
                _key339 = iprot.readString();
                {
                  org.apache.thrift.protocol.TList _list341 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
                  _val340 = new ArrayList<Mutation>(_list341.size);
                  for (int _i342 = 0; _i342 < _list341.size; ++_i342)
                  {
                    Mutation _elem343;
                    _elem343 = new Mutation();
                    _elem343.read(iprot);
                    _val340.add(_elem343);
                  }
                }
                _val336.put(_key339, _val340);
              }
            }
            struct.mutation_map.put(_key335, _val336);
          }
        }
        struct.setMutation_mapIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(batch_mutate_result.class, metaDataMap);
    }

    public batch_mutate_result() {
    }

    public batch_mutate_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public batch_mutate_result(batch_mutate_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public batch_mutate_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public batch_mutate_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public batch_mutate_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("batch_mutate_result(");
      boolean first = true;

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

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

    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 batch_mutate_resultStandardSchemeFactory implements SchemeFactory {
      public batch_mutate_resultStandardScheme getScheme() {
        return new batch_mutate_resultStandardScheme();
      }
    }

    private static class batch_mutate_resultStandardScheme extends StandardScheme<batch_mutate_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, batch_mutate_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, batch_mutate_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class batch_mutate_resultTupleSchemeFactory implements SchemeFactory {
      public batch_mutate_resultTupleScheme getScheme() {
        return new batch_mutate_resultTupleScheme();
      }
    }

    private static class batch_mutate_resultTupleScheme extends TupleScheme<batch_mutate_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, batch_mutate_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, batch_mutate_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField MUTATION_MAP_FIELD_DESC = new org.apache.thrift.protocol.TField("mutation_map", org.apache.thrift.protocol.TType.MAP, (short)1);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", 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 atomic_batch_mutate_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new atomic_batch_mutate_argsTupleSchemeFactory());
    }

    public Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency_level; // 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 {
      MUTATION_MAP((short)1, "mutation_map"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY_LEVEL((short)2, "consistency_level");

      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: // MUTATION_MAP
            return MUTATION_MAP;
          case 2: // CONSISTENCY_LEVEL
            return CONSISTENCY_LEVEL;
          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.MUTATION_MAP, new org.apache.thrift.meta_data.FieldMetaData("mutation_map", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true), 
              new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
                  new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
                  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, Mutation.class))))));
      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(atomic_batch_mutate_args.class, metaDataMap);
    }

    public atomic_batch_mutate_args() {
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

    public atomic_batch_mutate_args(
      Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map,
      ConsistencyLevel consistency_level)
    {
      this();
      this.mutation_map = mutation_map;
      this.consistency_level = consistency_level;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public atomic_batch_mutate_args(atomic_batch_mutate_args other) {
      if (other.isSetMutation_map()) {
        Map<ByteBuffer,Map<String,List<Mutation>>> __this__mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>(other.mutation_map.size());
        for (Map.Entry<ByteBuffer, Map<String,List<Mutation>>> other_element : other.mutation_map.entrySet()) {

          ByteBuffer other_element_key = other_element.getKey();
          Map<String,List<Mutation>> other_element_value = other_element.getValue();

          ByteBuffer __this__mutation_map_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
;

          Map<String,List<Mutation>> __this__mutation_map_copy_value = new HashMap<String,List<Mutation>>(other_element_value.size());
          for (Map.Entry<String, List<Mutation>> other_element_value_element : other_element_value.entrySet()) {

            String other_element_value_element_key = other_element_value_element.getKey();
            List<Mutation> other_element_value_element_value = other_element_value_element.getValue();

            String __this__mutation_map_copy_value_copy_key = other_element_value_element_key;

            List<Mutation> __this__mutation_map_copy_value_copy_value = new ArrayList<Mutation>(other_element_value_element_value.size());
            for (Mutation other_element_value_element_value_element : other_element_value_element_value) {
              __this__mutation_map_copy_value_copy_value.add(new Mutation(other_element_value_element_value_element));
            }

            __this__mutation_map_copy_value.put(__this__mutation_map_copy_value_copy_key, __this__mutation_map_copy_value_copy_value);
          }

          __this__mutation_map.put(__this__mutation_map_copy_key, __this__mutation_map_copy_value);
        }
        this.mutation_map = __this__mutation_map;
      }
      if (other.isSetConsistency_level()) {
        this.consistency_level = other.consistency_level;
      }
    }

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

    @Override
    public void clear() {
      this.mutation_map = null;
      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;

    }

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

    public void putToMutation_map(ByteBuffer key, Map<String,List<Mutation>> val) {
      if (this.mutation_map == null) {
        this.mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>();
      }
      this.mutation_map.put(key, val);
    }

    public Map<ByteBuffer,Map<String,List<Mutation>>> getMutation_map() {
      return this.mutation_map;
    }

    public atomic_batch_mutate_args setMutation_map(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map) {
      this.mutation_map = mutation_map;
      return this;
    }

    public void unsetMutation_map() {
      this.mutation_map = null;
    }

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

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

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency_level() {
      return this.consistency_level;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public atomic_batch_mutate_args setConsistency_level(ConsistencyLevel consistency_level) {
      this.consistency_level = consistency_level;
      return this;
    }

    public void unsetConsistency_level() {
      this.consistency_level = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case MUTATION_MAP:
        if (value == null) {
          unsetMutation_map();
        } else {
          setMutation_map((Map<ByteBuffer,Map<String,List<Mutation>>>)value);
        }
        break;

      case CONSISTENCY_LEVEL:
        if (value == null) {
          unsetConsistency_level();
        } else {
          setConsistency_level((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case MUTATION_MAP:
        return getMutation_map();

      case CONSISTENCY_LEVEL:
        return getConsistency_level();

      }
      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 MUTATION_MAP:
        return isSetMutation_map();
      case CONSISTENCY_LEVEL:
        return isSetConsistency_level();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_mutation_map = true && this.isSetMutation_map();
      boolean that_present_mutation_map = true && that.isSetMutation_map();
      if (this_present_mutation_map || that_present_mutation_map) {
        if (!(this_present_mutation_map && that_present_mutation_map))
          return false;
        if (!this.mutation_map.equals(that.mutation_map))
          return false;
      }

      boolean this_present_consistency_level = true && this.isSetConsistency_level();
      boolean that_present_consistency_level = true && that.isSetConsistency_level();
      if (this_present_consistency_level || that_present_consistency_level) {
        if (!(this_present_consistency_level && that_present_consistency_level))
          return false;
        if (!this.consistency_level.equals(that.consistency_level))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_mutation_map = true && (isSetMutation_map());
      builder.append(present_mutation_map);
      if (present_mutation_map)
        builder.append(mutation_map);

      boolean present_consistency_level = true && (isSetConsistency_level());
      builder.append(present_consistency_level);
      if (present_consistency_level)
        builder.append(consistency_level.getValue());

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetMutation_map()).compareTo(other.isSetMutation_map());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetMutation_map()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.mutation_map, other.mutation_map);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(other.isSetConsistency_level());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency_level()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, other.consistency_level);
        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("atomic_batch_mutate_args(");
      boolean first = true;

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

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

    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 atomic_batch_mutate_argsStandardSchemeFactory implements SchemeFactory {
      public atomic_batch_mutate_argsStandardScheme getScheme() {
        return new atomic_batch_mutate_argsStandardScheme();
      }
    }

    private static class atomic_batch_mutate_argsStandardScheme extends StandardScheme<atomic_batch_mutate_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, atomic_batch_mutate_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: // MUTATION_MAP
              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map344 = iprot.readMapBegin();
                  struct.mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>(2*_map344.size);
                  for (int _i345 = 0; _i345 < _map344.size; ++_i345)
                  {
                    ByteBuffer _key346;
                    Map<String,List<Mutation>> _val347;
                    _key346 = iprot.readBinary();
                    {
                      org.apache.thrift.protocol.TMap _map348 = iprot.readMapBegin();
                      _val347 = new HashMap<String,List<Mutation>>(2*_map348.size);
                      for (int _i349 = 0; _i349 < _map348.size; ++_i349)
                      {
                        String _key350;
                        List<Mutation> _val351;
                        _key350 = iprot.readString();
                        {
                          org.apache.thrift.protocol.TList _list352 = iprot.readListBegin();
                          _val351 = new ArrayList<Mutation>(_list352.size);
                          for (int _i353 = 0; _i353 < _list352.size; ++_i353)
                          {
                            Mutation _elem354;
                            _elem354 = new Mutation();
                            _elem354.read(iprot);
                            _val351.add(_elem354);
                          }
                          iprot.readListEnd();
                        }
                        _val347.put(_key350, _val351);
                      }
                      iprot.readMapEnd();
                    }
                    struct.mutation_map.put(_key346, _val347);
                  }
                  iprot.readMapEnd();
                }
                struct.setMutation_mapIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // CONSISTENCY_LEVEL
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistency_levelIsSet(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, atomic_batch_mutate_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.mutation_map != null) {
          oprot.writeFieldBegin(MUTATION_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.MAP, struct.mutation_map.size()));
            for (Map.Entry<ByteBuffer, Map<String,List<Mutation>>> _iter355 : struct.mutation_map.entrySet())
            {
              oprot.writeBinary(_iter355.getKey());
              {
                oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, _iter355.getValue().size()));
                for (Map.Entry<String, List<Mutation>> _iter356 : _iter355.getValue().entrySet())
                {
                  oprot.writeString(_iter356.getKey());
                  {
                    oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, _iter356.getValue().size()));
                    for (Mutation _iter357 : _iter356.getValue())
                    {
                      _iter357.write(oprot);
                    }
                    oprot.writeListEnd();
                  }
                }
                oprot.writeMapEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.consistency_level != null) {
          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
          oprot.writeI32(struct.consistency_level.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class atomic_batch_mutate_argsTupleSchemeFactory implements SchemeFactory {
      public atomic_batch_mutate_argsTupleScheme getScheme() {
        return new atomic_batch_mutate_argsTupleScheme();
      }
    }

    private static class atomic_batch_mutate_argsTupleScheme extends TupleScheme<atomic_batch_mutate_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, atomic_batch_mutate_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        {
          oprot.writeI32(struct.mutation_map.size());
          for (Map.Entry<ByteBuffer, Map<String,List<Mutation>>> _iter358 : struct.mutation_map.entrySet())
          {
            oprot.writeBinary(_iter358.getKey());
            {
              oprot.writeI32(_iter358.getValue().size());
              for (Map.Entry<String, List<Mutation>> _iter359 : _iter358.getValue().entrySet())
              {
                oprot.writeString(_iter359.getKey());
                {
                  oprot.writeI32(_iter359.getValue().size());
                  for (Mutation _iter360 : _iter359.getValue())
                  {
                    _iter360.write(oprot);
                  }
                }
              }
            }
          }
        }
        oprot.writeI32(struct.consistency_level.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, atomic_batch_mutate_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        {
          org.apache.thrift.protocol.TMap _map361 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.MAP, iprot.readI32());
          struct.mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>(2*_map361.size);
          for (int _i362 = 0; _i362 < _map361.size; ++_i362)
          {
            ByteBuffer _key363;
            Map<String,List<Mutation>> _val364;
            _key363 = iprot.readBinary();
            {
              org.apache.thrift.protocol.TMap _map365 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
              _val364 = new HashMap<String,List<Mutation>>(2*_map365.size);
              for (int _i366 = 0; _i366 < _map365.size; ++_i366)
              {
                String _key367;
                List<Mutation> _val368;
                _key367 = iprot.readString();
                {
                  org.apache.thrift.protocol.TList _list369 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
                  _val368 = new ArrayList<Mutation>(_list369.size);
                  for (int _i370 = 0; _i370 < _list369.size; ++_i370)
                  {
                    Mutation _elem371;
                    _elem371 = new Mutation();
                    _elem371.read(iprot);
                    _val368.add(_elem371);
                  }
                }
                _val364.put(_key367, _val368);
              }
            }
            struct.mutation_map.put(_key363, _val364);
          }
        }
        struct.setMutation_mapIsSet(true);
        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistency_levelIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(atomic_batch_mutate_result.class, metaDataMap);
    }

    public atomic_batch_mutate_result() {
    }

    public atomic_batch_mutate_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public atomic_batch_mutate_result(atomic_batch_mutate_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public atomic_batch_mutate_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public atomic_batch_mutate_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public atomic_batch_mutate_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("atomic_batch_mutate_result(");
      boolean first = true;

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

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

    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 atomic_batch_mutate_resultStandardSchemeFactory implements SchemeFactory {
      public atomic_batch_mutate_resultStandardScheme getScheme() {
        return new atomic_batch_mutate_resultStandardScheme();
      }
    }

    private static class atomic_batch_mutate_resultStandardScheme extends StandardScheme<atomic_batch_mutate_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, atomic_batch_mutate_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, atomic_batch_mutate_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class atomic_batch_mutate_resultTupleSchemeFactory implements SchemeFactory {
      public atomic_batch_mutate_resultTupleScheme getScheme() {
        return new atomic_batch_mutate_resultTupleScheme();
      }
    }

    private static class atomic_batch_mutate_resultTupleScheme extends TupleScheme<atomic_batch_mutate_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, atomic_batch_mutate_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, atomic_batch_mutate_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField CFNAME_FIELD_DESC = new org.apache.thrift.protocol.TField("cfname", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public String cfname; // 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 {
      CFNAME((short)1, "cfname");

      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: // CFNAME
            return CFNAME;
          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.CFNAME, new org.apache.thrift.meta_data.FieldMetaData("cfname", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(truncate_args.class, metaDataMap);
    }

    public truncate_args() {
    }

    public truncate_args(
      String cfname)
    {
      this();
      this.cfname = cfname;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public truncate_args(truncate_args other) {
      if (other.isSetCfname()) {
        this.cfname = other.cfname;
      }
    }

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

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

    public String getCfname() {
      return this.cfname;
    }

    public truncate_args setCfname(String cfname) {
      this.cfname = cfname;
      return this;
    }

    public void unsetCfname() {
      this.cfname = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case CFNAME:
        if (value == null) {
          unsetCfname();
        } else {
          setCfname((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case CFNAME:
        return getCfname();

      }
      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 CFNAME:
        return isSetCfname();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_cfname = true && this.isSetCfname();
      boolean that_present_cfname = true && that.isSetCfname();
      if (this_present_cfname || that_present_cfname) {
        if (!(this_present_cfname && that_present_cfname))
          return false;
        if (!this.cfname.equals(that.cfname))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_cfname = true && (isSetCfname());
      builder.append(present_cfname);
      if (present_cfname)
        builder.append(cfname);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetCfname()).compareTo(other.isSetCfname());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCfname()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cfname, other.cfname);
        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("truncate_args(");
      boolean first = true;

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

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

    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 truncate_argsStandardSchemeFactory implements SchemeFactory {
      public truncate_argsStandardScheme getScheme() {
        return new truncate_argsStandardScheme();
      }
    }

    private static class truncate_argsStandardScheme extends StandardScheme<truncate_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, truncate_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: // CFNAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.cfname = iprot.readString();
                struct.setCfnameIsSet(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, truncate_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.cfname != null) {
          oprot.writeFieldBegin(CFNAME_FIELD_DESC);
          oprot.writeString(struct.cfname);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class truncate_argsTupleSchemeFactory implements SchemeFactory {
      public truncate_argsTupleScheme getScheme() {
        return new truncate_argsTupleScheme();
      }
    }

    private static class truncate_argsTupleScheme extends TupleScheme<truncate_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, truncate_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.cfname);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, truncate_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.cfname = iprot.readString();
        struct.setCfnameIsSet(true);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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 {
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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(truncate_result.class, metaDataMap);
    }

    public truncate_result() {
    }

    public truncate_result(
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public truncate_result(truncate_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public truncate_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public truncate_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public truncate_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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("truncate_result(");
      boolean first = true;

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

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

    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 truncate_resultStandardSchemeFactory implements SchemeFactory {
      public truncate_resultStandardScheme getScheme() {
        return new truncate_resultStandardScheme();
      }
    }

    private static class truncate_resultStandardScheme extends StandardScheme<truncate_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, truncate_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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, truncate_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class truncate_resultTupleSchemeFactory implements SchemeFactory {
      public truncate_resultTupleScheme getScheme() {
        return new truncate_resultTupleScheme();
      }
    }

    private static class truncate_resultTupleScheme extends TupleScheme<truncate_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, truncate_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        if (struct.isSetUe()) {
          optionals.set(1);
        }
        if (struct.isSetTe()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, truncate_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("request", 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_multi_slice_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new get_multi_slice_argsTupleSchemeFactory());
    }

    public MultiSliceRequest request; // 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 {
      REQUEST((short)1, "request");

      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: // REQUEST
            return REQUEST;
          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.REQUEST, new org.apache.thrift.meta_data.FieldMetaData("request", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MultiSliceRequest.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_multi_slice_args.class, metaDataMap);
    }

    public get_multi_slice_args() {
    }

    public get_multi_slice_args(
      MultiSliceRequest request)
    {
      this();
      this.request = request;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_multi_slice_args(get_multi_slice_args other) {
      if (other.isSetRequest()) {
        this.request = new MultiSliceRequest(other.request);
      }
    }

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

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

    public MultiSliceRequest getRequest() {
      return this.request;
    }

    public get_multi_slice_args setRequest(MultiSliceRequest request) {
      this.request = request;
      return this;
    }

    public void unsetRequest() {
      this.request = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case REQUEST:
        if (value == null) {
          unsetRequest();
        } else {
          setRequest((MultiSliceRequest)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case REQUEST:
        return getRequest();

      }
      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 REQUEST:
        return isSetRequest();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_request = true && this.isSetRequest();
      boolean that_present_request = true && that.isSetRequest();
      if (this_present_request || that_present_request) {
        if (!(this_present_request && that_present_request))
          return false;
        if (!this.request.equals(that.request))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_request = true && (isSetRequest());
      builder.append(present_request);
      if (present_request)
        builder.append(request);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetRequest()).compareTo(other.isSetRequest());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetRequest()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.request, other.request);
        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_multi_slice_args(");
      boolean first = true;

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

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

    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_multi_slice_argsStandardSchemeFactory implements SchemeFactory {
      public get_multi_slice_argsStandardScheme getScheme() {
        return new get_multi_slice_argsStandardScheme();
      }
    }

    private static class get_multi_slice_argsStandardScheme extends StandardScheme<get_multi_slice_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_multi_slice_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: // REQUEST
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.request = new MultiSliceRequest();
                struct.request.read(iprot);
                struct.setRequestIsSet(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_multi_slice_args struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class get_multi_slice_argsTupleSchemeFactory implements SchemeFactory {
      public get_multi_slice_argsTupleScheme getScheme() {
        return new get_multi_slice_argsTupleScheme();
      }
    }

    private static class get_multi_slice_argsTupleScheme extends TupleScheme<get_multi_slice_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_multi_slice_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.request = new MultiSliceRequest();
        struct.request.read(iprot);
        struct.setRequestIsSet(true);
      }
    }

  }

  public static class get_multi_slice_result implements org.apache.thrift.TBase<get_multi_slice_result, get_multi_slice_result._Fields>, java.io.Serializable, Cloneable, Comparable<get_multi_slice_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_multi_slice_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);

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

    public List<ColumnOrSuperColumn> success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          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, ColumnOrSuperColumn.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", 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_multi_slice_result.class, metaDataMap);
    }

    public get_multi_slice_result() {
    }

    public get_multi_slice_result(
      List<ColumnOrSuperColumn> success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public get_multi_slice_result(get_multi_slice_result other) {
      if (other.isSetSuccess()) {
        List<ColumnOrSuperColumn> __this__success = new ArrayList<ColumnOrSuperColumn>(other.success.size());
        for (ColumnOrSuperColumn other_element : other.success) {
          __this__success.add(new ColumnOrSuperColumn(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
    }

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

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

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

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

    public get_multi_slice_result setSuccess(List<ColumnOrSuperColumn> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public get_multi_slice_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

    public UnavailableException getUe() {
      return this.ue;
    }

    public get_multi_slice_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

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

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

    public TimedOutException getTe() {
      return this.te;
    }

    public get_multi_slice_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(get_multi_slice_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        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_multi_slice_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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_multi_slice_resultStandardSchemeFactory implements SchemeFactory {
      public get_multi_slice_resultStandardScheme getScheme() {
        return new get_multi_slice_resultStandardScheme();
      }
    }

    private static class get_multi_slice_resultStandardScheme extends StandardScheme<get_multi_slice_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, get_multi_slice_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 _list372 = iprot.readListBegin();
                  struct.success = new ArrayList<ColumnOrSuperColumn>(_list372.size);
                  for (int _i373 = 0; _i373 < _list372.size; ++_i373)
                  {
                    ColumnOrSuperColumn _elem374;
                    _elem374 = new ColumnOrSuperColumn();
                    _elem374.read(iprot);
                    struct.success.add(_elem374);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(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_multi_slice_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 (ColumnOrSuperColumn _iter375 : struct.success)
            {
              _iter375.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class get_multi_slice_resultTupleSchemeFactory implements SchemeFactory {
      public get_multi_slice_resultTupleScheme getScheme() {
        return new get_multi_slice_resultTupleScheme();
      }
    }

    private static class get_multi_slice_resultTupleScheme extends TupleScheme<get_multi_slice_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, get_multi_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        oprot.writeBitSet(optionals, 4);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (ColumnOrSuperColumn _iter376 : struct.success)
            {
              _iter376.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, get_multi_slice_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(4);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list377 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<ColumnOrSuperColumn>(_list377.size);
            for (int _i378 = 0; _i378 < _list377.size; ++_i378)
            {
              ColumnOrSuperColumn _elem379;
              _elem379 = new ColumnOrSuperColumn();
              _elem379.read(iprot);
              struct.success.add(_elem379);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_schema_versions_args.class, metaDataMap);
    }

    public describe_schema_versions_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_schema_versions_args(describe_schema_versions_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_schema_versions_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_schema_versions_argsStandardSchemeFactory implements SchemeFactory {
      public describe_schema_versions_argsStandardScheme getScheme() {
        return new describe_schema_versions_argsStandardScheme();
      }
    }

    private static class describe_schema_versions_argsStandardScheme extends StandardScheme<describe_schema_versions_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_schema_versions_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) {
            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, describe_schema_versions_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_schema_versions_argsTupleSchemeFactory implements SchemeFactory {
      public describe_schema_versions_argsTupleScheme getScheme() {
        return new describe_schema_versions_argsTupleScheme();
      }
    }

    private static class describe_schema_versions_argsTupleScheme extends TupleScheme<describe_schema_versions_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_schema_versions_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_schema_versions_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_schema_versions_resultTupleSchemeFactory());
    }

    public Map<String,List<String>> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
                  new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_schema_versions_result.class, metaDataMap);
    }

    public describe_schema_versions_result() {
    }

    public describe_schema_versions_result(
      Map<String,List<String>> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_schema_versions_result(describe_schema_versions_result other) {
      if (other.isSetSuccess()) {
        Map<String,List<String>> __this__success = new HashMap<String,List<String>>(other.success.size());
        for (Map.Entry<String, List<String>> other_element : other.success.entrySet()) {

          String other_element_key = other_element.getKey();
          List<String> other_element_value = other_element.getValue();

          String __this__success_copy_key = other_element_key;

          List<String> __this__success_copy_value = new ArrayList<String>(other_element_value);

          __this__success.put(__this__success_copy_key, __this__success_copy_value);
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

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

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

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

    public void putToSuccess(String key, List<String> val) {
      if (this.success == null) {
        this.success = new HashMap<String,List<String>>();
      }
      this.success.put(key, val);
    }

    public Map<String,List<String>> getSuccess() {
      return this.success;
    }

    public describe_schema_versions_result setSuccess(Map<String,List<String>> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_schema_versions_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_schema_versions_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_schema_versions_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 describe_schema_versions_resultStandardSchemeFactory implements SchemeFactory {
      public describe_schema_versions_resultStandardScheme getScheme() {
        return new describe_schema_versions_resultStandardScheme();
      }
    }

    private static class describe_schema_versions_resultStandardScheme extends StandardScheme<describe_schema_versions_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_schema_versions_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.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map380 = iprot.readMapBegin();
                  struct.success = new HashMap<String,List<String>>(2*_map380.size);
                  for (int _i381 = 0; _i381 < _map380.size; ++_i381)
                  {
                    String _key382;
                    List<String> _val383;
                    _key382 = iprot.readString();
                    {
                      org.apache.thrift.protocol.TList _list384 = iprot.readListBegin();
                      _val383 = new ArrayList<String>(_list384.size);
                      for (int _i385 = 0; _i385 < _list384.size; ++_i385)
                      {
                        String _elem386;
                        _elem386 = iprot.readString();
                        _val383.add(_elem386);
                      }
                      iprot.readListEnd();
                    }
                    struct.success.put(_key382, _val383);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_schema_versions_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, struct.success.size()));
            for (Map.Entry<String, List<String>> _iter387 : struct.success.entrySet())
            {
              oprot.writeString(_iter387.getKey());
              {
                oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, _iter387.getValue().size()));
                for (String _iter388 : _iter387.getValue())
                {
                  oprot.writeString(_iter388);
                }
                oprot.writeListEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_schema_versions_resultTupleSchemeFactory implements SchemeFactory {
      public describe_schema_versions_resultTupleScheme getScheme() {
        return new describe_schema_versions_resultTupleScheme();
      }
    }

    private static class describe_schema_versions_resultTupleScheme extends TupleScheme<describe_schema_versions_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_schema_versions_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, List<String>> _iter389 : struct.success.entrySet())
            {
              oprot.writeString(_iter389.getKey());
              {
                oprot.writeI32(_iter389.getValue().size());
                for (String _iter390 : _iter389.getValue())
                {
                  oprot.writeString(_iter390);
                }
              }
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_schema_versions_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map391 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
            struct.success = new HashMap<String,List<String>>(2*_map391.size);
            for (int _i392 = 0; _i392 < _map391.size; ++_i392)
            {
              String _key393;
              List<String> _val394;
              _key393 = iprot.readString();
              {
                org.apache.thrift.protocol.TList _list395 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
                _val394 = new ArrayList<String>(_list395.size);
                for (int _i396 = 0; _i396 < _list395.size; ++_i396)
                {
                  String _elem397;
                  _elem397 = iprot.readString();
                  _val394.add(_elem397);
                }
              }
              struct.success.put(_key393, _val394);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_keyspaces_args.class, metaDataMap);
    }

    public describe_keyspaces_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_keyspaces_args(describe_keyspaces_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_keyspaces_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_keyspaces_argsStandardSchemeFactory implements SchemeFactory {
      public describe_keyspaces_argsStandardScheme getScheme() {
        return new describe_keyspaces_argsStandardScheme();
      }
    }

    private static class describe_keyspaces_argsStandardScheme extends StandardScheme<describe_keyspaces_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_keyspaces_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) {
            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, describe_keyspaces_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_keyspaces_argsTupleSchemeFactory implements SchemeFactory {
      public describe_keyspaces_argsTupleScheme getScheme() {
        return new describe_keyspaces_argsTupleScheme();
      }
    }

    private static class describe_keyspaces_argsTupleScheme extends TupleScheme<describe_keyspaces_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_keyspaces_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

  public static class describe_keyspaces_result implements org.apache.thrift.TBase<describe_keyspaces_result, describe_keyspaces_result._Fields>, java.io.Serializable, Cloneable, Comparable<describe_keyspaces_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_keyspaces_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_keyspaces_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_keyspaces_resultTupleSchemeFactory());
    }

    public List<KsDef> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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, KsDef.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_keyspaces_result.class, metaDataMap);
    }

    public describe_keyspaces_result() {
    }

    public describe_keyspaces_result(
      List<KsDef> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_keyspaces_result(describe_keyspaces_result other) {
      if (other.isSetSuccess()) {
        List<KsDef> __this__success = new ArrayList<KsDef>(other.success.size());
        for (KsDef other_element : other.success) {
          __this__success.add(new KsDef(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

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

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

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

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

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

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

    public describe_keyspaces_result setSuccess(List<KsDef> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_keyspaces_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_keyspaces_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_keyspaces_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 describe_keyspaces_resultStandardSchemeFactory implements SchemeFactory {
      public describe_keyspaces_resultStandardScheme getScheme() {
        return new describe_keyspaces_resultStandardScheme();
      }
    }

    private static class describe_keyspaces_resultStandardScheme extends StandardScheme<describe_keyspaces_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_keyspaces_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 _list398 = iprot.readListBegin();
                  struct.success = new ArrayList<KsDef>(_list398.size);
                  for (int _i399 = 0; _i399 < _list398.size; ++_i399)
                  {
                    KsDef _elem400;
                    _elem400 = new KsDef();
                    _elem400.read(iprot);
                    struct.success.add(_elem400);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_keyspaces_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 (KsDef _iter401 : struct.success)
            {
              _iter401.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_keyspaces_resultTupleSchemeFactory implements SchemeFactory {
      public describe_keyspaces_resultTupleScheme getScheme() {
        return new describe_keyspaces_resultTupleScheme();
      }
    }

    private static class describe_keyspaces_resultTupleScheme extends TupleScheme<describe_keyspaces_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_keyspaces_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (KsDef _iter402 : struct.success)
            {
              _iter402.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_keyspaces_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 _list403 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<KsDef>(_list403.size);
            for (int _i404 = 0; _i404 < _list403.size; ++_i404)
            {
              KsDef _elem405;
              _elem405 = new KsDef();
              _elem405.read(iprot);
              struct.success.add(_elem405);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_cluster_name_args.class, metaDataMap);
    }

    public describe_cluster_name_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_cluster_name_args(describe_cluster_name_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_cluster_name_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_cluster_name_argsStandardSchemeFactory implements SchemeFactory {
      public describe_cluster_name_argsStandardScheme getScheme() {
        return new describe_cluster_name_argsStandardScheme();
      }
    }

    private static class describe_cluster_name_argsStandardScheme extends StandardScheme<describe_cluster_name_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_cluster_name_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) {
            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, describe_cluster_name_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_cluster_name_argsTupleSchemeFactory implements SchemeFactory {
      public describe_cluster_name_argsTupleScheme getScheme() {
        return new describe_cluster_name_argsTupleScheme();
      }
    }

    private static class describe_cluster_name_argsTupleScheme extends TupleScheme<describe_cluster_name_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_cluster_name_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

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

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

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

    public String success; // 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");

      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;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_cluster_name_result.class, metaDataMap);
    }

    public describe_cluster_name_result() {
    }

    public describe_cluster_name_result(
      String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_cluster_name_result(describe_cluster_name_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

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

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

    public describe_cluster_name_result setSuccess(String 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 void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      }
    }

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

      }
      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();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_cluster_name_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;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("describe_cluster_name_result(");
      boolean first = true;

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

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

    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 describe_cluster_name_resultStandardSchemeFactory implements SchemeFactory {
      public describe_cluster_name_resultStandardScheme getScheme() {
        return new describe_cluster_name_resultStandardScheme();
      }
    }

    private static class describe_cluster_name_resultStandardScheme extends StandardScheme<describe_cluster_name_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_cluster_name_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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, describe_cluster_name_result struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class describe_cluster_name_resultTupleSchemeFactory implements SchemeFactory {
      public describe_cluster_name_resultTupleScheme getScheme() {
        return new describe_cluster_name_resultTupleScheme();
      }
    }

    private static class describe_cluster_name_resultTupleScheme extends TupleScheme<describe_cluster_name_result> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_cluster_name_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_version_args.class, metaDataMap);
    }

    public describe_version_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_version_args(describe_version_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_version_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_version_argsStandardSchemeFactory implements SchemeFactory {
      public describe_version_argsStandardScheme getScheme() {
        return new describe_version_argsStandardScheme();
      }
    }

    private static class describe_version_argsStandardScheme extends StandardScheme<describe_version_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_version_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) {
            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, describe_version_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_version_argsTupleSchemeFactory implements SchemeFactory {
      public describe_version_argsTupleScheme getScheme() {
        return new describe_version_argsTupleScheme();
      }
    }

    private static class describe_version_argsTupleScheme extends TupleScheme<describe_version_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_version_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

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

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

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

    public String success; // 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");

      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;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_version_result.class, metaDataMap);
    }

    public describe_version_result() {
    }

    public describe_version_result(
      String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_version_result(describe_version_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

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

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

    public describe_version_result setSuccess(String 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 void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      }
    }

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

      }
      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();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_version_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;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("describe_version_result(");
      boolean first = true;

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

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

    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 describe_version_resultStandardSchemeFactory implements SchemeFactory {
      public describe_version_resultStandardScheme getScheme() {
        return new describe_version_resultStandardScheme();
      }
    }

    private static class describe_version_resultStandardScheme extends StandardScheme<describe_version_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_version_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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, describe_version_result struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class describe_version_resultTupleSchemeFactory implements SchemeFactory {
      public describe_version_resultTupleScheme getScheme() {
        return new describe_version_resultTupleScheme();
      }
    }

    private static class describe_version_resultTupleScheme extends TupleScheme<describe_version_result> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_version_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEYSPACE_FIELD_DESC = new org.apache.thrift.protocol.TField("keyspace", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public String keyspace; // 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 {
      KEYSPACE((short)1, "keyspace");

      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: // KEYSPACE
            return KEYSPACE;
          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.KEYSPACE, new org.apache.thrift.meta_data.FieldMetaData("keyspace", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_ring_args.class, metaDataMap);
    }

    public describe_ring_args() {
    }

    public describe_ring_args(
      String keyspace)
    {
      this();
      this.keyspace = keyspace;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_ring_args(describe_ring_args other) {
      if (other.isSetKeyspace()) {
        this.keyspace = other.keyspace;
      }
    }

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

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

    public String getKeyspace() {
      return this.keyspace;
    }

    public describe_ring_args setKeyspace(String keyspace) {
      this.keyspace = keyspace;
      return this;
    }

    public void unsetKeyspace() {
      this.keyspace = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYSPACE:
        if (value == null) {
          unsetKeyspace();
        } else {
          setKeyspace((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYSPACE:
        return getKeyspace();

      }
      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 KEYSPACE:
        return isSetKeyspace();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_keyspace = true && this.isSetKeyspace();
      boolean that_present_keyspace = true && that.isSetKeyspace();
      if (this_present_keyspace || that_present_keyspace) {
        if (!(this_present_keyspace && that_present_keyspace))
          return false;
        if (!this.keyspace.equals(that.keyspace))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keyspace = true && (isSetKeyspace());
      builder.append(present_keyspace);
      if (present_keyspace)
        builder.append(keyspace);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeyspace()).compareTo(other.isSetKeyspace());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeyspace()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyspace, other.keyspace);
        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("describe_ring_args(");
      boolean first = true;

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

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

    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 describe_ring_argsStandardSchemeFactory implements SchemeFactory {
      public describe_ring_argsStandardScheme getScheme() {
        return new describe_ring_argsStandardScheme();
      }
    }

    private static class describe_ring_argsStandardScheme extends StandardScheme<describe_ring_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_ring_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: // KEYSPACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.keyspace = iprot.readString();
                struct.setKeyspaceIsSet(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, describe_ring_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keyspace != null) {
          oprot.writeFieldBegin(KEYSPACE_FIELD_DESC);
          oprot.writeString(struct.keyspace);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_ring_argsTupleSchemeFactory implements SchemeFactory {
      public describe_ring_argsTupleScheme getScheme() {
        return new describe_ring_argsTupleScheme();
      }
    }

    private static class describe_ring_argsTupleScheme extends TupleScheme<describe_ring_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_ring_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.keyspace);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_ring_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.keyspace = iprot.readString();
        struct.setKeyspaceIsSet(true);
      }
    }

  }

  public static class describe_ring_result implements org.apache.thrift.TBase<describe_ring_result, describe_ring_result._Fields>, java.io.Serializable, Cloneable, Comparable<describe_ring_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_ring_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_ring_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_ring_resultTupleSchemeFactory());
    }

    public List<TokenRange> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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, TokenRange.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_ring_result.class, metaDataMap);
    }

    public describe_ring_result() {
    }

    public describe_ring_result(
      List<TokenRange> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_ring_result(describe_ring_result other) {
      if (other.isSetSuccess()) {
        List<TokenRange> __this__success = new ArrayList<TokenRange>(other.success.size());
        for (TokenRange other_element : other.success) {
          __this__success.add(new TokenRange(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

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

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

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

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

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

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

    public describe_ring_result setSuccess(List<TokenRange> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_ring_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_ring_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_ring_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 describe_ring_resultStandardSchemeFactory implements SchemeFactory {
      public describe_ring_resultStandardScheme getScheme() {
        return new describe_ring_resultStandardScheme();
      }
    }

    private static class describe_ring_resultStandardScheme extends StandardScheme<describe_ring_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_ring_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 _list406 = iprot.readListBegin();
                  struct.success = new ArrayList<TokenRange>(_list406.size);
                  for (int _i407 = 0; _i407 < _list406.size; ++_i407)
                  {
                    TokenRange _elem408;
                    _elem408 = new TokenRange();
                    _elem408.read(iprot);
                    struct.success.add(_elem408);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_ring_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 (TokenRange _iter409 : struct.success)
            {
              _iter409.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_ring_resultTupleSchemeFactory implements SchemeFactory {
      public describe_ring_resultTupleScheme getScheme() {
        return new describe_ring_resultTupleScheme();
      }
    }

    private static class describe_ring_resultTupleScheme extends TupleScheme<describe_ring_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_ring_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (TokenRange _iter410 : struct.success)
            {
              _iter410.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_ring_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 _list411 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<TokenRange>(_list411.size);
            for (int _i412 = 0; _i412 < _list411.size; ++_i412)
            {
              TokenRange _elem413;
              _elem413 = new TokenRange();
              _elem413.read(iprot);
              struct.success.add(_elem413);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEYSPACE_FIELD_DESC = new org.apache.thrift.protocol.TField("keyspace", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public String keyspace; // 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 {
      KEYSPACE((short)1, "keyspace");

      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: // KEYSPACE
            return KEYSPACE;
          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.KEYSPACE, new org.apache.thrift.meta_data.FieldMetaData("keyspace", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_local_ring_args.class, metaDataMap);
    }

    public describe_local_ring_args() {
    }

    public describe_local_ring_args(
      String keyspace)
    {
      this();
      this.keyspace = keyspace;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_local_ring_args(describe_local_ring_args other) {
      if (other.isSetKeyspace()) {
        this.keyspace = other.keyspace;
      }
    }

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

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

    public String getKeyspace() {
      return this.keyspace;
    }

    public describe_local_ring_args setKeyspace(String keyspace) {
      this.keyspace = keyspace;
      return this;
    }

    public void unsetKeyspace() {
      this.keyspace = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYSPACE:
        if (value == null) {
          unsetKeyspace();
        } else {
          setKeyspace((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYSPACE:
        return getKeyspace();

      }
      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 KEYSPACE:
        return isSetKeyspace();
      }
      throw new IllegalStateException();
    }

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

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

      boolean this_present_keyspace = true && this.isSetKeyspace();
      boolean that_present_keyspace = true && that.isSetKeyspace();
      if (this_present_keyspace || that_present_keyspace) {
        if (!(this_present_keyspace && that_present_keyspace))
          return false;
        if (!this.keyspace.equals(that.keyspace))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keyspace = true && (isSetKeyspace());
      builder.append(present_keyspace);
      if (present_keyspace)
        builder.append(keyspace);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeyspace()).compareTo(other.isSetKeyspace());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeyspace()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyspace, other.keyspace);
        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("describe_local_ring_args(");
      boolean first = true;

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

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

    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 describe_local_ring_argsStandardSchemeFactory implements SchemeFactory {
      public describe_local_ring_argsStandardScheme getScheme() {
        return new describe_local_ring_argsStandardScheme();
      }
    }

    private static class describe_local_ring_argsStandardScheme extends StandardScheme<describe_local_ring_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_local_ring_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: // KEYSPACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.keyspace = iprot.readString();
                struct.setKeyspaceIsSet(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, describe_local_ring_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keyspace != null) {
          oprot.writeFieldBegin(KEYSPACE_FIELD_DESC);
          oprot.writeString(struct.keyspace);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_local_ring_argsTupleSchemeFactory implements SchemeFactory {
      public describe_local_ring_argsTupleScheme getScheme() {
        return new describe_local_ring_argsTupleScheme();
      }
    }

    private static class describe_local_ring_argsTupleScheme extends TupleScheme<describe_local_ring_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_local_ring_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.keyspace);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_local_ring_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.keyspace = iprot.readString();
        struct.setKeyspaceIsSet(true);
      }
    }

  }

  public static class describe_local_ring_result implements org.apache.thrift.TBase<describe_local_ring_result, describe_local_ring_result._Fields>, java.io.Serializable, Cloneable, Comparable<describe_local_ring_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_local_ring_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_local_ring_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_local_ring_resultTupleSchemeFactory());
    }

    public List<TokenRange> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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, TokenRange.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_local_ring_result.class, metaDataMap);
    }

    public describe_local_ring_result() {
    }

    public describe_local_ring_result(
      List<TokenRange> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_local_ring_result(describe_local_ring_result other) {
      if (other.isSetSuccess()) {
        List<TokenRange> __this__success = new ArrayList<TokenRange>(other.success.size());
        for (TokenRange other_element : other.success) {
          __this__success.add(new TokenRange(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

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

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

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

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

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

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

    public describe_local_ring_result setSuccess(List<TokenRange> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_local_ring_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_local_ring_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_local_ring_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 describe_local_ring_resultStandardSchemeFactory implements SchemeFactory {
      public describe_local_ring_resultStandardScheme getScheme() {
        return new describe_local_ring_resultStandardScheme();
      }
    }

    private static class describe_local_ring_resultStandardScheme extends StandardScheme<describe_local_ring_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_local_ring_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 _list414 = iprot.readListBegin();
                  struct.success = new ArrayList<TokenRange>(_list414.size);
                  for (int _i415 = 0; _i415 < _list414.size; ++_i415)
                  {
                    TokenRange _elem416;
                    _elem416 = new TokenRange();
                    _elem416.read(iprot);
                    struct.success.add(_elem416);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_local_ring_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 (TokenRange _iter417 : struct.success)
            {
              _iter417.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_local_ring_resultTupleSchemeFactory implements SchemeFactory {
      public describe_local_ring_resultTupleScheme getScheme() {
        return new describe_local_ring_resultTupleScheme();
      }
    }

    private static class describe_local_ring_resultTupleScheme extends TupleScheme<describe_local_ring_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_local_ring_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (TokenRange _iter418 : struct.success)
            {
              _iter418.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_local_ring_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 _list419 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<TokenRange>(_list419.size);
            for (int _i420 = 0; _i420 < _list419.size; ++_i420)
            {
              TokenRange _elem421;
              _elem421 = new TokenRange();
              _elem421.read(iprot);
              struct.success.add(_elem421);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_token_map_args.class, metaDataMap);
    }

    public describe_token_map_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_token_map_args(describe_token_map_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_token_map_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_token_map_argsStandardSchemeFactory implements SchemeFactory {
      public describe_token_map_argsStandardScheme getScheme() {
        return new describe_token_map_argsStandardScheme();
      }
    }

    private static class describe_token_map_argsStandardScheme extends StandardScheme<describe_token_map_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_token_map_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) {
            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, describe_token_map_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_token_map_argsTupleSchemeFactory implements SchemeFactory {
      public describe_token_map_argsTupleScheme getScheme() {
        return new describe_token_map_argsTupleScheme();
      }
    }

    private static class describe_token_map_argsTupleScheme extends TupleScheme<describe_token_map_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_token_map_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_token_map_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_token_map_resultTupleSchemeFactory());
    }

    public Map<String,String> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_token_map_result.class, metaDataMap);
    }

    public describe_token_map_result() {
    }

    public describe_token_map_result(
      Map<String,String> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_token_map_result(describe_token_map_result other) {
      if (other.isSetSuccess()) {
        Map<String,String> __this__success = new HashMap<String,String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

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

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

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

    public void putToSuccess(String key, String val) {
      if (this.success == null) {
        this.success = new HashMap<String,String>();
      }
      this.success.put(key, val);
    }

    public Map<String,String> getSuccess() {
      return this.success;
    }

    public describe_token_map_result setSuccess(Map<String,String> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_token_map_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

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

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

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

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

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

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_token_map_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_token_map_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

    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 describe_token_map_resultStandardSchemeFactory implements SchemeFactory {
      public describe_token_map_resultStandardScheme getScheme() {
        return new describe_token_map_resultStandardScheme();
      }
    }

    private static class describe_token_map_resultStandardScheme extends StandardScheme<describe_token_map_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_token_map_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.MAP) {
                {
                  org.apache.thrift.protocol.TMap _map422 = iprot.readMapBegin();
                  struct.success = new HashMap<String,String>(2*_map422.size);
                  for (int _i423 = 0; _i423 < _map422.size; ++_i423)
                  {
                    String _key424;
                    String _val425;
                    _key424 = iprot.readString();
                    _val425 = iprot.readString();
                    struct.success.put(_key424, _val425);
                  }
                  iprot.readMapEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_token_map_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
            for (Map.Entry<String, String> _iter426 : struct.success.entrySet())
            {
              oprot.writeString(_iter426.getKey());
              oprot.writeString(_iter426.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_token_map_resultTupleSchemeFactory implements SchemeFactory {
      public describe_token_map_resultTupleScheme getScheme() {
        return new describe_token_map_resultTupleScheme();
      }
    }

    private static class describe_token_map_resultTupleScheme extends TupleScheme<describe_token_map_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_token_map_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (Map.Entry<String, String> _iter427 : struct.success.entrySet())
            {
              oprot.writeString(_iter427.getKey());
              oprot.writeString(_iter427.getValue());
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_token_map_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TMap _map428 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new HashMap<String,String>(2*_map428.size);
            for (int _i429 = 0; _i429 < _map428.size; ++_i429)
            {
              String _key430;
              String _val431;
              _key430 = iprot.readString();
              _val431 = iprot.readString();
              struct.success.put(_key430, _val431);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_partitioner_args.class, metaDataMap);
    }

    public describe_partitioner_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_partitioner_args(describe_partitioner_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_partitioner_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_partitioner_argsStandardSchemeFactory implements SchemeFactory {
      public describe_partitioner_argsStandardScheme getScheme() {
        return new describe_partitioner_argsStandardScheme();
      }
    }

    private static class describe_partitioner_argsStandardScheme extends StandardScheme<describe_partitioner_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_partitioner_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) {
            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, describe_partitioner_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_partitioner_argsTupleSchemeFactory implements SchemeFactory {
      public describe_partitioner_argsTupleScheme getScheme() {
        return new describe_partitioner_argsTupleScheme();
      }
    }

    private static class describe_partitioner_argsTupleScheme extends TupleScheme<describe_partitioner_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_partitioner_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

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

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

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

    public String success; // 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");

      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;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_partitioner_result.class, metaDataMap);
    }

    public describe_partitioner_result() {
    }

    public describe_partitioner_result(
      String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_partitioner_result(describe_partitioner_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

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

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

    public describe_partitioner_result setSuccess(String 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 void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      }
    }

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

      }
      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();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_partitioner_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;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("describe_partitioner_result(");
      boolean first = true;

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

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

    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 describe_partitioner_resultStandardSchemeFactory implements SchemeFactory {
      public describe_partitioner_resultStandardScheme getScheme() {
        return new describe_partitioner_resultStandardScheme();
      }
    }

    private static class describe_partitioner_resultStandardScheme extends StandardScheme<describe_partitioner_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_partitioner_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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, describe_partitioner_result struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class describe_partitioner_resultTupleSchemeFactory implements SchemeFactory {
      public describe_partitioner_resultTupleScheme getScheme() {
        return new describe_partitioner_resultTupleScheme();
      }
    }

    private static class describe_partitioner_resultTupleScheme extends TupleScheme<describe_partitioner_result> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_partitioner_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
      }
    }

  }

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


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


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

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_snitch_args.class, metaDataMap);
    }

    public describe_snitch_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_snitch_args(describe_snitch_args other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

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

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

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      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("describe_snitch_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

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

    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 describe_snitch_argsStandardSchemeFactory implements SchemeFactory {
      public describe_snitch_argsStandardScheme getScheme() {
        return new describe_snitch_argsStandardScheme();
      }
    }

    private static class describe_snitch_argsStandardScheme extends StandardScheme<describe_snitch_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_snitch_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) {
            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, describe_snitch_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_snitch_argsTupleSchemeFactory implements SchemeFactory {
      public describe_snitch_argsTupleScheme getScheme() {
        return new describe_snitch_argsTupleScheme();
      }
    }

    private static class describe_snitch_argsTupleScheme extends TupleScheme<describe_snitch_args> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_snitch_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

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

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

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

    public String success; // 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");

      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;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_snitch_result.class, metaDataMap);
    }

    public describe_snitch_result() {
    }

    public describe_snitch_result(
      String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_snitch_result(describe_snitch_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

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

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

    public describe_snitch_result setSuccess(String 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 void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      }
    }

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

      }
      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();
      }
      throw new IllegalStateException();
    }

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

    public boolean equals(describe_snitch_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;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      return builder.toHashCode();
    }

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

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("describe_snitch_result(");
      boolean first = true;

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

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

    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 describe_snitch_resultStandardSchemeFactory implements SchemeFactory {
      public describe_snitch_resultStandardScheme getScheme() {
        return new describe_snitch_resultStandardScheme();
      }
    }

    private static class describe_snitch_resultStandardScheme extends StandardScheme<describe_snitch_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_snitch_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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, describe_snitch_result struct) throws org.apache.thrift.TException {
        struct.validate();

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

    }

    private static class describe_snitch_resultTupleSchemeFactory implements SchemeFactory {
      public describe_snitch_resultTupleScheme getScheme() {
        return new describe_snitch_resultTupleScheme();
      }
    }

    private static class describe_snitch_resultTupleScheme extends TupleScheme<describe_snitch_result> {

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

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_snitch_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField KEYSPACE_FIELD_DESC = new org.apache.thrift.protocol.TField("keyspace", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public String keyspace; // 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 {
      KEYSPACE((short)1, "keyspace");

      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: // KEYSPACE
            return KEYSPACE;
          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.KEYSPACE, new org.apache.thrift.meta_data.FieldMetaData("keyspace", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(describe_keyspace_args.class, metaDataMap);
    }

    public describe_keyspace_args() {
    }

    public describe_keyspace_args(
      String keyspace)
    {
      this();
      this.keyspace = keyspace;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_keyspace_args(describe_keyspace_args other) {
      if (other.isSetKeyspace()) {
        this.keyspace = other.keyspace;
      }
    }

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

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

    public String getKeyspace() {
      return this.keyspace;
    }

    public describe_keyspace_args setKeyspace(String keyspace) {
      this.keyspace = keyspace;
      return this;
    }

    public void unsetKeyspace() {
      this.keyspace = null;
    }

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

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

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYSPACE:
        if (value == null) {
          unsetKeyspace();
        } else {
          setKeyspace((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYSPACE:
        return getKeyspace();

      }
      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 KEYSPACE:
        return isSetKeyspace();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof describe_keyspace_args)
        return this.equals((describe_keyspace_args)that);
      return false;
    }

    public boolean equals(describe_keyspace_args that) {
      if (that == null)
        return false;

      boolean this_present_keyspace = true && this.isSetKeyspace();
      boolean that_present_keyspace = true && that.isSetKeyspace();
      if (this_present_keyspace || that_present_keyspace) {
        if (!(this_present_keyspace && that_present_keyspace))
          return false;
        if (!this.keyspace.equals(that.keyspace))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keyspace = true && (isSetKeyspace());
      builder.append(present_keyspace);
      if (present_keyspace)
        builder.append(keyspace);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(describe_keyspace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeyspace()).compareTo(other.isSetKeyspace());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeyspace()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyspace, other.keyspace);
        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("describe_keyspace_args(");
      boolean first = true;

      sb.append("keyspace:");
      if (this.keyspace == null) {
        sb.append("null");
      } else {
        sb.append(this.keyspace);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (keyspace == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'keyspace' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 describe_keyspace_argsStandardSchemeFactory implements SchemeFactory {
      public describe_keyspace_argsStandardScheme getScheme() {
        return new describe_keyspace_argsStandardScheme();
      }
    }

    private static class describe_keyspace_argsStandardScheme extends StandardScheme<describe_keyspace_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_keyspace_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: // KEYSPACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.keyspace = iprot.readString();
                struct.setKeyspaceIsSet(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, describe_keyspace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keyspace != null) {
          oprot.writeFieldBegin(KEYSPACE_FIELD_DESC);
          oprot.writeString(struct.keyspace);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_keyspace_argsTupleSchemeFactory implements SchemeFactory {
      public describe_keyspace_argsTupleScheme getScheme() {
        return new describe_keyspace_argsTupleScheme();
      }
    }

    private static class describe_keyspace_argsTupleScheme extends TupleScheme<describe_keyspace_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.keyspace);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.keyspace = iprot.readString();
        struct.setKeyspaceIsSet(true);
      }
    }

  }

  public static class describe_keyspace_result implements org.apache.thrift.TBase<describe_keyspace_result, describe_keyspace_result._Fields>, java.io.Serializable, Cloneable, Comparable<describe_keyspace_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_keyspace_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 NFE_FIELD_DESC = new org.apache.thrift.protocol.TField("nfe", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_keyspace_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_keyspace_resultTupleSchemeFactory());
    }

    public KsDef success; // required
    public NotFoundException nfe; // required
    public InvalidRequestException ire; // 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"),
      NFE((short)1, "nfe"),
      IRE((short)2, "ire");

      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: // NFE
            return NFE;
          case 2: // IRE
            return IRE;
          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, KsDef.class)));
      tmpMap.put(_Fields.NFE, new org.apache.thrift.meta_data.FieldMetaData("nfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_keyspace_result.class, metaDataMap);
    }

    public describe_keyspace_result() {
    }

    public describe_keyspace_result(
      KsDef success,
      NotFoundException nfe,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.nfe = nfe;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_keyspace_result(describe_keyspace_result other) {
      if (other.isSetSuccess()) {
        this.success = new KsDef(other.success);
      }
      if (other.isSetNfe()) {
        this.nfe = new NotFoundException(other.nfe);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

    public describe_keyspace_result deepCopy() {
      return new describe_keyspace_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.nfe = null;
      this.ire = null;
    }

    public KsDef getSuccess() {
      return this.success;
    }

    public describe_keyspace_result setSuccess(KsDef 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 NotFoundException getNfe() {
      return this.nfe;
    }

    public describe_keyspace_result setNfe(NotFoundException nfe) {
      this.nfe = nfe;
      return this;
    }

    public void unsetNfe() {
      this.nfe = null;
    }

    /** Returns true if field nfe is set (has been assigned a value) and false otherwise */
    public boolean isSetNfe() {
      return this.nfe != null;
    }

    public void setNfeIsSet(boolean value) {
      if (!value) {
        this.nfe = null;
      }
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_keyspace_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((KsDef)value);
        }
        break;

      case NFE:
        if (value == null) {
          unsetNfe();
        } else {
          setNfe((NotFoundException)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case NFE:
        return getNfe();

      case IRE:
        return getIre();

      }
      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 NFE:
        return isSetNfe();
      case IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof describe_keyspace_result)
        return this.equals((describe_keyspace_result)that);
      return false;
    }

    public boolean equals(describe_keyspace_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_nfe = true && this.isSetNfe();
      boolean that_present_nfe = true && that.isSetNfe();
      if (this_present_nfe || that_present_nfe) {
        if (!(this_present_nfe && that_present_nfe))
          return false;
        if (!this.nfe.equals(that.nfe))
          return false;
      }

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_nfe = true && (isSetNfe());
      builder.append(present_nfe);
      if (present_nfe)
        builder.append(nfe);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(describe_keyspace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetNfe()).compareTo(other.isSetNfe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNfe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nfe, other.nfe);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_keyspace_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("nfe:");
      if (this.nfe == null) {
        sb.append("null");
      } else {
        sb.append(this.nfe);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 describe_keyspace_resultStandardSchemeFactory implements SchemeFactory {
      public describe_keyspace_resultStandardScheme getScheme() {
        return new describe_keyspace_resultStandardScheme();
      }
    }

    private static class describe_keyspace_resultStandardScheme extends StandardScheme<describe_keyspace_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_keyspace_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 KsDef();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // NFE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.nfe = new NotFoundException();
                struct.nfe.read(iprot);
                struct.setNfeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_keyspace_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.nfe != null) {
          oprot.writeFieldBegin(NFE_FIELD_DESC);
          struct.nfe.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_keyspace_resultTupleSchemeFactory implements SchemeFactory {
      public describe_keyspace_resultTupleScheme getScheme() {
        return new describe_keyspace_resultTupleScheme();
      }
    }

    private static class describe_keyspace_resultTupleScheme extends TupleScheme<describe_keyspace_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetNfe()) {
          optionals.set(1);
        }
        if (struct.isSetIre()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetNfe()) {
          struct.nfe.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = new KsDef();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.nfe = new NotFoundException();
          struct.nfe.read(iprot);
          struct.setNfeIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

  public static class describe_splits_args implements org.apache.thrift.TBase<describe_splits_args, describe_splits_args._Fields>, java.io.Serializable, Cloneable, Comparable<describe_splits_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_splits_args");

    private static final org.apache.thrift.protocol.TField CF_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("cfName", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField START_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("start_token", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField END_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("end_token", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField KEYS_PER_SPLIT_FIELD_DESC = new org.apache.thrift.protocol.TField("keys_per_split", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new describe_splits_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_splits_argsTupleSchemeFactory());
    }

    public String cfName; // required
    public String start_token; // required
    public String end_token; // required
    public int keys_per_split; // 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 {
      CF_NAME((short)1, "cfName"),
      START_TOKEN((short)2, "start_token"),
      END_TOKEN((short)3, "end_token"),
      KEYS_PER_SPLIT((short)4, "keys_per_split");

      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: // CF_NAME
            return CF_NAME;
          case 2: // START_TOKEN
            return START_TOKEN;
          case 3: // END_TOKEN
            return END_TOKEN;
          case 4: // KEYS_PER_SPLIT
            return KEYS_PER_SPLIT;
          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 __KEYS_PER_SPLIT_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    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.CF_NAME, new org.apache.thrift.meta_data.FieldMetaData("cfName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.START_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("start_token", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.END_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("end_token", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.KEYS_PER_SPLIT, new org.apache.thrift.meta_data.FieldMetaData("keys_per_split", 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(describe_splits_args.class, metaDataMap);
    }

    public describe_splits_args() {
    }

    public describe_splits_args(
      String cfName,
      String start_token,
      String end_token,
      int keys_per_split)
    {
      this();
      this.cfName = cfName;
      this.start_token = start_token;
      this.end_token = end_token;
      this.keys_per_split = keys_per_split;
      setKeys_per_splitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_splits_args(describe_splits_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetCfName()) {
        this.cfName = other.cfName;
      }
      if (other.isSetStart_token()) {
        this.start_token = other.start_token;
      }
      if (other.isSetEnd_token()) {
        this.end_token = other.end_token;
      }
      this.keys_per_split = other.keys_per_split;
    }

    public describe_splits_args deepCopy() {
      return new describe_splits_args(this);
    }

    @Override
    public void clear() {
      this.cfName = null;
      this.start_token = null;
      this.end_token = null;
      setKeys_per_splitIsSet(false);
      this.keys_per_split = 0;
    }

    public String getCfName() {
      return this.cfName;
    }

    public describe_splits_args setCfName(String cfName) {
      this.cfName = cfName;
      return this;
    }

    public void unsetCfName() {
      this.cfName = null;
    }

    /** Returns true if field cfName is set (has been assigned a value) and false otherwise */
    public boolean isSetCfName() {
      return this.cfName != null;
    }

    public void setCfNameIsSet(boolean value) {
      if (!value) {
        this.cfName = null;
      }
    }

    public String getStart_token() {
      return this.start_token;
    }

    public describe_splits_args setStart_token(String start_token) {
      this.start_token = start_token;
      return this;
    }

    public void unsetStart_token() {
      this.start_token = null;
    }

    /** Returns true if field start_token is set (has been assigned a value) and false otherwise */
    public boolean isSetStart_token() {
      return this.start_token != null;
    }

    public void setStart_tokenIsSet(boolean value) {
      if (!value) {
        this.start_token = null;
      }
    }

    public String getEnd_token() {
      return this.end_token;
    }

    public describe_splits_args setEnd_token(String end_token) {
      this.end_token = end_token;
      return this;
    }

    public void unsetEnd_token() {
      this.end_token = null;
    }

    /** Returns true if field end_token is set (has been assigned a value) and false otherwise */
    public boolean isSetEnd_token() {
      return this.end_token != null;
    }

    public void setEnd_tokenIsSet(boolean value) {
      if (!value) {
        this.end_token = null;
      }
    }

    public int getKeys_per_split() {
      return this.keys_per_split;
    }

    public describe_splits_args setKeys_per_split(int keys_per_split) {
      this.keys_per_split = keys_per_split;
      setKeys_per_splitIsSet(true);
      return this;
    }

    public void unsetKeys_per_split() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __KEYS_PER_SPLIT_ISSET_ID);
    }

    /** Returns true if field keys_per_split is set (has been assigned a value) and false otherwise */
    public boolean isSetKeys_per_split() {
      return EncodingUtils.testBit(__isset_bitfield, __KEYS_PER_SPLIT_ISSET_ID);
    }

    public void setKeys_per_splitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __KEYS_PER_SPLIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case CF_NAME:
        if (value == null) {
          unsetCfName();
        } else {
          setCfName((String)value);
        }
        break;

      case START_TOKEN:
        if (value == null) {
          unsetStart_token();
        } else {
          setStart_token((String)value);
        }
        break;

      case END_TOKEN:
        if (value == null) {
          unsetEnd_token();
        } else {
          setEnd_token((String)value);
        }
        break;

      case KEYS_PER_SPLIT:
        if (value == null) {
          unsetKeys_per_split();
        } else {
          setKeys_per_split((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case CF_NAME:
        return getCfName();

      case START_TOKEN:
        return getStart_token();

      case END_TOKEN:
        return getEnd_token();

      case KEYS_PER_SPLIT:
        return Integer.valueOf(getKeys_per_split());

      }
      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 CF_NAME:
        return isSetCfName();
      case START_TOKEN:
        return isSetStart_token();
      case END_TOKEN:
        return isSetEnd_token();
      case KEYS_PER_SPLIT:
        return isSetKeys_per_split();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof describe_splits_args)
        return this.equals((describe_splits_args)that);
      return false;
    }

    public boolean equals(describe_splits_args that) {
      if (that == null)
        return false;

      boolean this_present_cfName = true && this.isSetCfName();
      boolean that_present_cfName = true && that.isSetCfName();
      if (this_present_cfName || that_present_cfName) {
        if (!(this_present_cfName && that_present_cfName))
          return false;
        if (!this.cfName.equals(that.cfName))
          return false;
      }

      boolean this_present_start_token = true && this.isSetStart_token();
      boolean that_present_start_token = true && that.isSetStart_token();
      if (this_present_start_token || that_present_start_token) {
        if (!(this_present_start_token && that_present_start_token))
          return false;
        if (!this.start_token.equals(that.start_token))
          return false;
      }

      boolean this_present_end_token = true && this.isSetEnd_token();
      boolean that_present_end_token = true && that.isSetEnd_token();
      if (this_present_end_token || that_present_end_token) {
        if (!(this_present_end_token && that_present_end_token))
          return false;
        if (!this.end_token.equals(that.end_token))
          return false;
      }

      boolean this_present_keys_per_split = true;
      boolean that_present_keys_per_split = true;
      if (this_present_keys_per_split || that_present_keys_per_split) {
        if (!(this_present_keys_per_split && that_present_keys_per_split))
          return false;
        if (this.keys_per_split != that.keys_per_split)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_cfName = true && (isSetCfName());
      builder.append(present_cfName);
      if (present_cfName)
        builder.append(cfName);

      boolean present_start_token = true && (isSetStart_token());
      builder.append(present_start_token);
      if (present_start_token)
        builder.append(start_token);

      boolean present_end_token = true && (isSetEnd_token());
      builder.append(present_end_token);
      if (present_end_token)
        builder.append(end_token);

      boolean present_keys_per_split = true;
      builder.append(present_keys_per_split);
      if (present_keys_per_split)
        builder.append(keys_per_split);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(describe_splits_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetCfName()).compareTo(other.isSetCfName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCfName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cfName, other.cfName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetStart_token()).compareTo(other.isSetStart_token());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStart_token()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.start_token, other.start_token);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnd_token()).compareTo(other.isSetEnd_token());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnd_token()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.end_token, other.end_token);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetKeys_per_split()).compareTo(other.isSetKeys_per_split());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeys_per_split()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keys_per_split, other.keys_per_split);
        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("describe_splits_args(");
      boolean first = true;

      sb.append("cfName:");
      if (this.cfName == null) {
        sb.append("null");
      } else {
        sb.append(this.cfName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("start_token:");
      if (this.start_token == null) {
        sb.append("null");
      } else {
        sb.append(this.start_token);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("end_token:");
      if (this.end_token == null) {
        sb.append("null");
      } else {
        sb.append(this.end_token);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("keys_per_split:");
      sb.append(this.keys_per_split);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (cfName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'cfName' was not present! Struct: " + toString());
      }
      if (start_token == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'start_token' was not present! Struct: " + toString());
      }
      if (end_token == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'end_token' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'keys_per_split' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    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_bitfield = 0;
        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 describe_splits_argsStandardSchemeFactory implements SchemeFactory {
      public describe_splits_argsStandardScheme getScheme() {
        return new describe_splits_argsStandardScheme();
      }
    }

    private static class describe_splits_argsStandardScheme extends StandardScheme<describe_splits_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_splits_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: // CF_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.cfName = iprot.readString();
                struct.setCfNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // START_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.start_token = iprot.readString();
                struct.setStart_tokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // END_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.end_token = iprot.readString();
                struct.setEnd_tokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // KEYS_PER_SPLIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.keys_per_split = iprot.readI32();
                struct.setKeys_per_splitIsSet(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.isSetKeys_per_split()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'keys_per_split' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, describe_splits_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.cfName != null) {
          oprot.writeFieldBegin(CF_NAME_FIELD_DESC);
          oprot.writeString(struct.cfName);
          oprot.writeFieldEnd();
        }
        if (struct.start_token != null) {
          oprot.writeFieldBegin(START_TOKEN_FIELD_DESC);
          oprot.writeString(struct.start_token);
          oprot.writeFieldEnd();
        }
        if (struct.end_token != null) {
          oprot.writeFieldBegin(END_TOKEN_FIELD_DESC);
          oprot.writeString(struct.end_token);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(KEYS_PER_SPLIT_FIELD_DESC);
        oprot.writeI32(struct.keys_per_split);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_splits_argsTupleSchemeFactory implements SchemeFactory {
      public describe_splits_argsTupleScheme getScheme() {
        return new describe_splits_argsTupleScheme();
      }
    }

    private static class describe_splits_argsTupleScheme extends TupleScheme<describe_splits_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_splits_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.cfName);
        oprot.writeString(struct.start_token);
        oprot.writeString(struct.end_token);
        oprot.writeI32(struct.keys_per_split);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_splits_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.cfName = iprot.readString();
        struct.setCfNameIsSet(true);
        struct.start_token = iprot.readString();
        struct.setStart_tokenIsSet(true);
        struct.end_token = iprot.readString();
        struct.setEnd_tokenIsSet(true);
        struct.keys_per_split = iprot.readI32();
        struct.setKeys_per_splitIsSet(true);
      }
    }

  }

  public static class describe_splits_result implements org.apache.thrift.TBase<describe_splits_result, describe_splits_result._Fields>, java.io.Serializable, Cloneable, Comparable<describe_splits_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_splits_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_splits_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_splits_resultTupleSchemeFactory());
    }

    public List<String> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_splits_result.class, metaDataMap);
    }

    public describe_splits_result() {
    }

    public describe_splits_result(
      List<String> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_splits_result(describe_splits_result other) {
      if (other.isSetSuccess()) {
        List<String> __this__success = new ArrayList<String>(other.success);
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

    public describe_splits_result deepCopy() {
      return new describe_splits_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<String> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(String elem) {
      if (this.success == null) {
        this.success = new ArrayList<String>();
      }
      this.success.add(elem);
    }

    public List<String> getSuccess() {
      return this.success;
    }

    public describe_splits_result setSuccess(List<String> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_splits_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<String>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof describe_splits_result)
        return this.equals((describe_splits_result)that);
      return false;
    }

    public boolean equals(describe_splits_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(describe_splits_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_splits_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 describe_splits_resultStandardSchemeFactory implements SchemeFactory {
      public describe_splits_resultStandardScheme getScheme() {
        return new describe_splits_resultStandardScheme();
      }
    }

    private static class describe_splits_resultStandardScheme extends StandardScheme<describe_splits_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_splits_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 _list432 = iprot.readListBegin();
                  struct.success = new ArrayList<String>(_list432.size);
                  for (int _i433 = 0; _i433 < _list432.size; ++_i433)
                  {
                    String _elem434;
                    _elem434 = iprot.readString();
                    struct.success.add(_elem434);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_splits_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.STRING, struct.success.size()));
            for (String _iter435 : struct.success)
            {
              oprot.writeString(_iter435);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_splits_resultTupleSchemeFactory implements SchemeFactory {
      public describe_splits_resultTupleScheme getScheme() {
        return new describe_splits_resultTupleScheme();
      }
    }

    private static class describe_splits_resultTupleScheme extends TupleScheme<describe_splits_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_splits_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (String _iter436 : struct.success)
            {
              oprot.writeString(_iter436);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_splits_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 _list437 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
            struct.success = new ArrayList<String>(_list437.size);
            for (int _i438 = 0; _i438 < _list437.size; ++_i438)
            {
              String _elem439;
              _elem439 = iprot.readString();
              struct.success.add(_elem439);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

  public static class trace_next_query_args implements org.apache.thrift.TBase<trace_next_query_args, trace_next_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<trace_next_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("trace_next_query_args");


    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new trace_next_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new trace_next_query_argsTupleSchemeFactory());
    }


    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
;

      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) {
          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;
      }
    }
    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);
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(trace_next_query_args.class, metaDataMap);
    }

    public trace_next_query_args() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public trace_next_query_args(trace_next_query_args other) {
    }

    public trace_next_query_args deepCopy() {
      return new trace_next_query_args(this);
    }

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof trace_next_query_args)
        return this.equals((trace_next_query_args)that);
      return false;
    }

    public boolean equals(trace_next_query_args that) {
      if (that == null)
        return false;

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      return builder.toHashCode();
    }

    @Override
    public int compareTo(trace_next_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      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("trace_next_query_args(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 trace_next_query_argsStandardSchemeFactory implements SchemeFactory {
      public trace_next_query_argsStandardScheme getScheme() {
        return new trace_next_query_argsStandardScheme();
      }
    }

    private static class trace_next_query_argsStandardScheme extends StandardScheme<trace_next_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, trace_next_query_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) {
            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, trace_next_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class trace_next_query_argsTupleSchemeFactory implements SchemeFactory {
      public trace_next_query_argsTupleScheme getScheme() {
        return new trace_next_query_argsTupleScheme();
      }
    }

    private static class trace_next_query_argsTupleScheme extends TupleScheme<trace_next_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, trace_next_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, trace_next_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
      }
    }

  }

  public static class trace_next_query_result implements org.apache.thrift.TBase<trace_next_query_result, trace_next_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<trace_next_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("trace_next_query_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new trace_next_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new trace_next_query_resultTupleSchemeFactory());
    }

    public ByteBuffer success; // 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");

      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;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(trace_next_query_result.class, metaDataMap);
    }

    public trace_next_query_result() {
    }

    public trace_next_query_result(
      ByteBuffer success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public trace_next_query_result(trace_next_query_result other) {
      if (other.isSetSuccess()) {
        this.success = org.apache.thrift.TBaseHelper.copyBinary(other.success);
;
      }
    }

    public trace_next_query_result deepCopy() {
      return new trace_next_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public byte[] getSuccess() {
      setSuccess(org.apache.thrift.TBaseHelper.rightSize(success));
      return success == null ? null : success.array();
    }

    public ByteBuffer bufferForSuccess() {
      return success;
    }

    public trace_next_query_result setSuccess(byte[] success) {
      setSuccess(success == null ? (ByteBuffer)null : ByteBuffer.wrap(success));
      return this;
    }

    public trace_next_query_result setSuccess(ByteBuffer 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 void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((ByteBuffer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      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();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof trace_next_query_result)
        return this.equals((trace_next_query_result)that);
      return false;
    }

    public boolean equals(trace_next_query_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;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(trace_next_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("trace_next_query_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.success, sb);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 trace_next_query_resultStandardSchemeFactory implements SchemeFactory {
      public trace_next_query_resultStandardScheme getScheme() {
        return new trace_next_query_resultStandardScheme();
      }
    }

    private static class trace_next_query_resultStandardScheme extends StandardScheme<trace_next_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, trace_next_query_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.STRING) {
                struct.success = iprot.readBinary();
                struct.setSuccessIsSet(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, trace_next_query_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBinary(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class trace_next_query_resultTupleSchemeFactory implements SchemeFactory {
      public trace_next_query_resultTupleScheme getScheme() {
        return new trace_next_query_resultTupleScheme();
      }
    }

    private static class trace_next_query_resultTupleScheme extends TupleScheme<trace_next_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, trace_next_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBinary(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, trace_next_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBinary();
          struct.setSuccessIsSet(true);
        }
      }
    }

  }

  public static class describe_splits_ex_args implements org.apache.thrift.TBase<describe_splits_ex_args, describe_splits_ex_args._Fields>, java.io.Serializable, Cloneable, Comparable<describe_splits_ex_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_splits_ex_args");

    private static final org.apache.thrift.protocol.TField CF_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("cfName", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField START_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("start_token", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField END_TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("end_token", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField KEYS_PER_SPLIT_FIELD_DESC = new org.apache.thrift.protocol.TField("keys_per_split", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new describe_splits_ex_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_splits_ex_argsTupleSchemeFactory());
    }

    public String cfName; // required
    public String start_token; // required
    public String end_token; // required
    public int keys_per_split; // 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 {
      CF_NAME((short)1, "cfName"),
      START_TOKEN((short)2, "start_token"),
      END_TOKEN((short)3, "end_token"),
      KEYS_PER_SPLIT((short)4, "keys_per_split");

      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: // CF_NAME
            return CF_NAME;
          case 2: // START_TOKEN
            return START_TOKEN;
          case 3: // END_TOKEN
            return END_TOKEN;
          case 4: // KEYS_PER_SPLIT
            return KEYS_PER_SPLIT;
          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 __KEYS_PER_SPLIT_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    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.CF_NAME, new org.apache.thrift.meta_data.FieldMetaData("cfName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.START_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("start_token", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.END_TOKEN, new org.apache.thrift.meta_data.FieldMetaData("end_token", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.KEYS_PER_SPLIT, new org.apache.thrift.meta_data.FieldMetaData("keys_per_split", 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(describe_splits_ex_args.class, metaDataMap);
    }

    public describe_splits_ex_args() {
    }

    public describe_splits_ex_args(
      String cfName,
      String start_token,
      String end_token,
      int keys_per_split)
    {
      this();
      this.cfName = cfName;
      this.start_token = start_token;
      this.end_token = end_token;
      this.keys_per_split = keys_per_split;
      setKeys_per_splitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_splits_ex_args(describe_splits_ex_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetCfName()) {
        this.cfName = other.cfName;
      }
      if (other.isSetStart_token()) {
        this.start_token = other.start_token;
      }
      if (other.isSetEnd_token()) {
        this.end_token = other.end_token;
      }
      this.keys_per_split = other.keys_per_split;
    }

    public describe_splits_ex_args deepCopy() {
      return new describe_splits_ex_args(this);
    }

    @Override
    public void clear() {
      this.cfName = null;
      this.start_token = null;
      this.end_token = null;
      setKeys_per_splitIsSet(false);
      this.keys_per_split = 0;
    }

    public String getCfName() {
      return this.cfName;
    }

    public describe_splits_ex_args setCfName(String cfName) {
      this.cfName = cfName;
      return this;
    }

    public void unsetCfName() {
      this.cfName = null;
    }

    /** Returns true if field cfName is set (has been assigned a value) and false otherwise */
    public boolean isSetCfName() {
      return this.cfName != null;
    }

    public void setCfNameIsSet(boolean value) {
      if (!value) {
        this.cfName = null;
      }
    }

    public String getStart_token() {
      return this.start_token;
    }

    public describe_splits_ex_args setStart_token(String start_token) {
      this.start_token = start_token;
      return this;
    }

    public void unsetStart_token() {
      this.start_token = null;
    }

    /** Returns true if field start_token is set (has been assigned a value) and false otherwise */
    public boolean isSetStart_token() {
      return this.start_token != null;
    }

    public void setStart_tokenIsSet(boolean value) {
      if (!value) {
        this.start_token = null;
      }
    }

    public String getEnd_token() {
      return this.end_token;
    }

    public describe_splits_ex_args setEnd_token(String end_token) {
      this.end_token = end_token;
      return this;
    }

    public void unsetEnd_token() {
      this.end_token = null;
    }

    /** Returns true if field end_token is set (has been assigned a value) and false otherwise */
    public boolean isSetEnd_token() {
      return this.end_token != null;
    }

    public void setEnd_tokenIsSet(boolean value) {
      if (!value) {
        this.end_token = null;
      }
    }

    public int getKeys_per_split() {
      return this.keys_per_split;
    }

    public describe_splits_ex_args setKeys_per_split(int keys_per_split) {
      this.keys_per_split = keys_per_split;
      setKeys_per_splitIsSet(true);
      return this;
    }

    public void unsetKeys_per_split() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __KEYS_PER_SPLIT_ISSET_ID);
    }

    /** Returns true if field keys_per_split is set (has been assigned a value) and false otherwise */
    public boolean isSetKeys_per_split() {
      return EncodingUtils.testBit(__isset_bitfield, __KEYS_PER_SPLIT_ISSET_ID);
    }

    public void setKeys_per_splitIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __KEYS_PER_SPLIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case CF_NAME:
        if (value == null) {
          unsetCfName();
        } else {
          setCfName((String)value);
        }
        break;

      case START_TOKEN:
        if (value == null) {
          unsetStart_token();
        } else {
          setStart_token((String)value);
        }
        break;

      case END_TOKEN:
        if (value == null) {
          unsetEnd_token();
        } else {
          setEnd_token((String)value);
        }
        break;

      case KEYS_PER_SPLIT:
        if (value == null) {
          unsetKeys_per_split();
        } else {
          setKeys_per_split((Integer)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case CF_NAME:
        return getCfName();

      case START_TOKEN:
        return getStart_token();

      case END_TOKEN:
        return getEnd_token();

      case KEYS_PER_SPLIT:
        return Integer.valueOf(getKeys_per_split());

      }
      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 CF_NAME:
        return isSetCfName();
      case START_TOKEN:
        return isSetStart_token();
      case END_TOKEN:
        return isSetEnd_token();
      case KEYS_PER_SPLIT:
        return isSetKeys_per_split();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof describe_splits_ex_args)
        return this.equals((describe_splits_ex_args)that);
      return false;
    }

    public boolean equals(describe_splits_ex_args that) {
      if (that == null)
        return false;

      boolean this_present_cfName = true && this.isSetCfName();
      boolean that_present_cfName = true && that.isSetCfName();
      if (this_present_cfName || that_present_cfName) {
        if (!(this_present_cfName && that_present_cfName))
          return false;
        if (!this.cfName.equals(that.cfName))
          return false;
      }

      boolean this_present_start_token = true && this.isSetStart_token();
      boolean that_present_start_token = true && that.isSetStart_token();
      if (this_present_start_token || that_present_start_token) {
        if (!(this_present_start_token && that_present_start_token))
          return false;
        if (!this.start_token.equals(that.start_token))
          return false;
      }

      boolean this_present_end_token = true && this.isSetEnd_token();
      boolean that_present_end_token = true && that.isSetEnd_token();
      if (this_present_end_token || that_present_end_token) {
        if (!(this_present_end_token && that_present_end_token))
          return false;
        if (!this.end_token.equals(that.end_token))
          return false;
      }

      boolean this_present_keys_per_split = true;
      boolean that_present_keys_per_split = true;
      if (this_present_keys_per_split || that_present_keys_per_split) {
        if (!(this_present_keys_per_split && that_present_keys_per_split))
          return false;
        if (this.keys_per_split != that.keys_per_split)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_cfName = true && (isSetCfName());
      builder.append(present_cfName);
      if (present_cfName)
        builder.append(cfName);

      boolean present_start_token = true && (isSetStart_token());
      builder.append(present_start_token);
      if (present_start_token)
        builder.append(start_token);

      boolean present_end_token = true && (isSetEnd_token());
      builder.append(present_end_token);
      if (present_end_token)
        builder.append(end_token);

      boolean present_keys_per_split = true;
      builder.append(present_keys_per_split);
      if (present_keys_per_split)
        builder.append(keys_per_split);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(describe_splits_ex_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetCfName()).compareTo(other.isSetCfName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCfName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cfName, other.cfName);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetStart_token()).compareTo(other.isSetStart_token());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStart_token()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.start_token, other.start_token);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetEnd_token()).compareTo(other.isSetEnd_token());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEnd_token()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.end_token, other.end_token);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetKeys_per_split()).compareTo(other.isSetKeys_per_split());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeys_per_split()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keys_per_split, other.keys_per_split);
        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("describe_splits_ex_args(");
      boolean first = true;

      sb.append("cfName:");
      if (this.cfName == null) {
        sb.append("null");
      } else {
        sb.append(this.cfName);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("start_token:");
      if (this.start_token == null) {
        sb.append("null");
      } else {
        sb.append(this.start_token);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("end_token:");
      if (this.end_token == null) {
        sb.append("null");
      } else {
        sb.append(this.end_token);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("keys_per_split:");
      sb.append(this.keys_per_split);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (cfName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'cfName' was not present! Struct: " + toString());
      }
      if (start_token == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'start_token' was not present! Struct: " + toString());
      }
      if (end_token == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'end_token' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'keys_per_split' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    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_bitfield = 0;
        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 describe_splits_ex_argsStandardSchemeFactory implements SchemeFactory {
      public describe_splits_ex_argsStandardScheme getScheme() {
        return new describe_splits_ex_argsStandardScheme();
      }
    }

    private static class describe_splits_ex_argsStandardScheme extends StandardScheme<describe_splits_ex_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_splits_ex_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: // CF_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.cfName = iprot.readString();
                struct.setCfNameIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // START_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.start_token = iprot.readString();
                struct.setStart_tokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // END_TOKEN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.end_token = iprot.readString();
                struct.setEnd_tokenIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // KEYS_PER_SPLIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.keys_per_split = iprot.readI32();
                struct.setKeys_per_splitIsSet(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.isSetKeys_per_split()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'keys_per_split' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, describe_splits_ex_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.cfName != null) {
          oprot.writeFieldBegin(CF_NAME_FIELD_DESC);
          oprot.writeString(struct.cfName);
          oprot.writeFieldEnd();
        }
        if (struct.start_token != null) {
          oprot.writeFieldBegin(START_TOKEN_FIELD_DESC);
          oprot.writeString(struct.start_token);
          oprot.writeFieldEnd();
        }
        if (struct.end_token != null) {
          oprot.writeFieldBegin(END_TOKEN_FIELD_DESC);
          oprot.writeString(struct.end_token);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(KEYS_PER_SPLIT_FIELD_DESC);
        oprot.writeI32(struct.keys_per_split);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_splits_ex_argsTupleSchemeFactory implements SchemeFactory {
      public describe_splits_ex_argsTupleScheme getScheme() {
        return new describe_splits_ex_argsTupleScheme();
      }
    }

    private static class describe_splits_ex_argsTupleScheme extends TupleScheme<describe_splits_ex_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_splits_ex_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.cfName);
        oprot.writeString(struct.start_token);
        oprot.writeString(struct.end_token);
        oprot.writeI32(struct.keys_per_split);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_splits_ex_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.cfName = iprot.readString();
        struct.setCfNameIsSet(true);
        struct.start_token = iprot.readString();
        struct.setStart_tokenIsSet(true);
        struct.end_token = iprot.readString();
        struct.setEnd_tokenIsSet(true);
        struct.keys_per_split = iprot.readI32();
        struct.setKeys_per_splitIsSet(true);
      }
    }

  }

  public static class describe_splits_ex_result implements org.apache.thrift.TBase<describe_splits_ex_result, describe_splits_ex_result._Fields>, java.io.Serializable, Cloneable, Comparable<describe_splits_ex_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("describe_splits_ex_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 describe_splits_ex_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new describe_splits_ex_resultTupleSchemeFactory());
    }

    public List<CfSplit> success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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, CfSplit.class))));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(describe_splits_ex_result.class, metaDataMap);
    }

    public describe_splits_ex_result() {
    }

    public describe_splits_ex_result(
      List<CfSplit> success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public describe_splits_ex_result(describe_splits_ex_result other) {
      if (other.isSetSuccess()) {
        List<CfSplit> __this__success = new ArrayList<CfSplit>(other.success.size());
        for (CfSplit other_element : other.success) {
          __this__success.add(new CfSplit(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

    public describe_splits_ex_result deepCopy() {
      return new describe_splits_ex_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<CfSplit> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(CfSplit elem) {
      if (this.success == null) {
        this.success = new ArrayList<CfSplit>();
      }
      this.success.add(elem);
    }

    public List<CfSplit> getSuccess() {
      return this.success;
    }

    public describe_splits_ex_result setSuccess(List<CfSplit> 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public describe_splits_ex_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((List<CfSplit>)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof describe_splits_ex_result)
        return this.equals((describe_splits_ex_result)that);
      return false;
    }

    public boolean equals(describe_splits_ex_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(describe_splits_ex_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("describe_splits_ex_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 describe_splits_ex_resultStandardSchemeFactory implements SchemeFactory {
      public describe_splits_ex_resultStandardScheme getScheme() {
        return new describe_splits_ex_resultStandardScheme();
      }
    }

    private static class describe_splits_ex_resultStandardScheme extends StandardScheme<describe_splits_ex_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, describe_splits_ex_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 _list440 = iprot.readListBegin();
                  struct.success = new ArrayList<CfSplit>(_list440.size);
                  for (int _i441 = 0; _i441 < _list440.size; ++_i441)
                  {
                    CfSplit _elem442;
                    _elem442 = new CfSplit();
                    _elem442.read(iprot);
                    struct.success.add(_elem442);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, describe_splits_ex_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 (CfSplit _iter443 : struct.success)
            {
              _iter443.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class describe_splits_ex_resultTupleSchemeFactory implements SchemeFactory {
      public describe_splits_ex_resultTupleScheme getScheme() {
        return new describe_splits_ex_resultTupleScheme();
      }
    }

    private static class describe_splits_ex_resultTupleScheme extends TupleScheme<describe_splits_ex_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, describe_splits_ex_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (CfSplit _iter444 : struct.success)
            {
              _iter444.write(oprot);
            }
          }
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, describe_splits_ex_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 _list445 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new ArrayList<CfSplit>(_list445.size);
            for (int _i446 = 0; _i446 < _list445.size; ++_i446)
            {
              CfSplit _elem447;
              _elem447 = new CfSplit();
              _elem447.read(iprot);
              struct.success.add(_elem447);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

  public static class system_add_column_family_args implements org.apache.thrift.TBase<system_add_column_family_args, system_add_column_family_args._Fields>, java.io.Serializable, Cloneable, Comparable<system_add_column_family_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_add_column_family_args");

    private static final org.apache.thrift.protocol.TField CF_DEF_FIELD_DESC = new org.apache.thrift.protocol.TField("cf_def", 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 system_add_column_family_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_add_column_family_argsTupleSchemeFactory());
    }

    public CfDef cf_def; // 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 {
      CF_DEF((short)1, "cf_def");

      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: // CF_DEF
            return CF_DEF;
          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.CF_DEF, new org.apache.thrift.meta_data.FieldMetaData("cf_def", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CfDef.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(system_add_column_family_args.class, metaDataMap);
    }

    public system_add_column_family_args() {
    }

    public system_add_column_family_args(
      CfDef cf_def)
    {
      this();
      this.cf_def = cf_def;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_add_column_family_args(system_add_column_family_args other) {
      if (other.isSetCf_def()) {
        this.cf_def = new CfDef(other.cf_def);
      }
    }

    public system_add_column_family_args deepCopy() {
      return new system_add_column_family_args(this);
    }

    @Override
    public void clear() {
      this.cf_def = null;
    }

    public CfDef getCf_def() {
      return this.cf_def;
    }

    public system_add_column_family_args setCf_def(CfDef cf_def) {
      this.cf_def = cf_def;
      return this;
    }

    public void unsetCf_def() {
      this.cf_def = null;
    }

    /** Returns true if field cf_def is set (has been assigned a value) and false otherwise */
    public boolean isSetCf_def() {
      return this.cf_def != null;
    }

    public void setCf_defIsSet(boolean value) {
      if (!value) {
        this.cf_def = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case CF_DEF:
        if (value == null) {
          unsetCf_def();
        } else {
          setCf_def((CfDef)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case CF_DEF:
        return getCf_def();

      }
      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 CF_DEF:
        return isSetCf_def();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_add_column_family_args)
        return this.equals((system_add_column_family_args)that);
      return false;
    }

    public boolean equals(system_add_column_family_args that) {
      if (that == null)
        return false;

      boolean this_present_cf_def = true && this.isSetCf_def();
      boolean that_present_cf_def = true && that.isSetCf_def();
      if (this_present_cf_def || that_present_cf_def) {
        if (!(this_present_cf_def && that_present_cf_def))
          return false;
        if (!this.cf_def.equals(that.cf_def))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_cf_def = true && (isSetCf_def());
      builder.append(present_cf_def);
      if (present_cf_def)
        builder.append(cf_def);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_add_column_family_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetCf_def()).compareTo(other.isSetCf_def());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCf_def()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cf_def, other.cf_def);
        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("system_add_column_family_args(");
      boolean first = true;

      sb.append("cf_def:");
      if (this.cf_def == null) {
        sb.append("null");
      } else {
        sb.append(this.cf_def);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (cf_def == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'cf_def' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (cf_def != null) {
        cf_def.validate();
      }
    }

    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 system_add_column_family_argsStandardSchemeFactory implements SchemeFactory {
      public system_add_column_family_argsStandardScheme getScheme() {
        return new system_add_column_family_argsStandardScheme();
      }
    }

    private static class system_add_column_family_argsStandardScheme extends StandardScheme<system_add_column_family_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_add_column_family_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: // CF_DEF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.cf_def = new CfDef();
                struct.cf_def.read(iprot);
                struct.setCf_defIsSet(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, system_add_column_family_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.cf_def != null) {
          oprot.writeFieldBegin(CF_DEF_FIELD_DESC);
          struct.cf_def.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_add_column_family_argsTupleSchemeFactory implements SchemeFactory {
      public system_add_column_family_argsTupleScheme getScheme() {
        return new system_add_column_family_argsTupleScheme();
      }
    }

    private static class system_add_column_family_argsTupleScheme extends TupleScheme<system_add_column_family_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_add_column_family_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.cf_def.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_add_column_family_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.cf_def = new CfDef();
        struct.cf_def.read(iprot);
        struct.setCf_defIsSet(true);
      }
    }

  }

  public static class system_add_column_family_result implements org.apache.thrift.TBase<system_add_column_family_result, system_add_column_family_result._Fields>, java.io.Serializable, Cloneable, Comparable<system_add_column_family_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_add_column_family_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", 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 system_add_column_family_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_add_column_family_resultTupleSchemeFactory());
    }

    public String success; // required
    public InvalidRequestException ire; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      SDE((short)2, "sde");

      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: // IRE
            return IRE;
          case 2: // SDE
            return SDE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(system_add_column_family_result.class, metaDataMap);
    }

    public system_add_column_family_result() {
    }

    public system_add_column_family_result(
      String success,
      InvalidRequestException ire,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_add_column_family_result(system_add_column_family_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public system_add_column_family_result deepCopy() {
      return new system_add_column_family_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.sde = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public system_add_column_family_result setSuccess(String 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public system_add_column_family_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public system_add_column_family_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_add_column_family_result)
        return this.equals((system_add_column_family_result)that);
      return false;
    }

    public boolean equals(system_add_column_family_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_add_column_family_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("system_add_column_family_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 system_add_column_family_resultStandardSchemeFactory implements SchemeFactory {
      public system_add_column_family_resultStandardScheme getScheme() {
        return new system_add_column_family_resultStandardScheme();
      }
    }

    private static class system_add_column_family_resultStandardScheme extends StandardScheme<system_add_column_family_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_add_column_family_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, system_add_column_family_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_add_column_family_resultTupleSchemeFactory implements SchemeFactory {
      public system_add_column_family_resultTupleScheme getScheme() {
        return new system_add_column_family_resultTupleScheme();
      }
    }

    private static class system_add_column_family_resultTupleScheme extends TupleScheme<system_add_column_family_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_add_column_family_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetSde()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_add_column_family_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class system_drop_column_family_args implements org.apache.thrift.TBase<system_drop_column_family_args, system_drop_column_family_args._Fields>, java.io.Serializable, Cloneable, Comparable<system_drop_column_family_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_drop_column_family_args");

    private static final org.apache.thrift.protocol.TField COLUMN_FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("column_family", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new system_drop_column_family_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_drop_column_family_argsTupleSchemeFactory());
    }

    public String column_family; // 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 {
      COLUMN_FAMILY((short)1, "column_family");

      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: // COLUMN_FAMILY
            return COLUMN_FAMILY;
          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.COLUMN_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("column_family", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(system_drop_column_family_args.class, metaDataMap);
    }

    public system_drop_column_family_args() {
    }

    public system_drop_column_family_args(
      String column_family)
    {
      this();
      this.column_family = column_family;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_drop_column_family_args(system_drop_column_family_args other) {
      if (other.isSetColumn_family()) {
        this.column_family = other.column_family;
      }
    }

    public system_drop_column_family_args deepCopy() {
      return new system_drop_column_family_args(this);
    }

    @Override
    public void clear() {
      this.column_family = null;
    }

    public String getColumn_family() {
      return this.column_family;
    }

    public system_drop_column_family_args setColumn_family(String column_family) {
      this.column_family = column_family;
      return this;
    }

    public void unsetColumn_family() {
      this.column_family = null;
    }

    /** Returns true if field column_family is set (has been assigned a value) and false otherwise */
    public boolean isSetColumn_family() {
      return this.column_family != null;
    }

    public void setColumn_familyIsSet(boolean value) {
      if (!value) {
        this.column_family = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case COLUMN_FAMILY:
        if (value == null) {
          unsetColumn_family();
        } else {
          setColumn_family((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case COLUMN_FAMILY:
        return getColumn_family();

      }
      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 COLUMN_FAMILY:
        return isSetColumn_family();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_drop_column_family_args)
        return this.equals((system_drop_column_family_args)that);
      return false;
    }

    public boolean equals(system_drop_column_family_args that) {
      if (that == null)
        return false;

      boolean this_present_column_family = true && this.isSetColumn_family();
      boolean that_present_column_family = true && that.isSetColumn_family();
      if (this_present_column_family || that_present_column_family) {
        if (!(this_present_column_family && that_present_column_family))
          return false;
        if (!this.column_family.equals(that.column_family))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_column_family = true && (isSetColumn_family());
      builder.append(present_column_family);
      if (present_column_family)
        builder.append(column_family);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_drop_column_family_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetColumn_family()).compareTo(other.isSetColumn_family());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetColumn_family()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_family, other.column_family);
        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("system_drop_column_family_args(");
      boolean first = true;

      sb.append("column_family:");
      if (this.column_family == null) {
        sb.append("null");
      } else {
        sb.append(this.column_family);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (column_family == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_family' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 system_drop_column_family_argsStandardSchemeFactory implements SchemeFactory {
      public system_drop_column_family_argsStandardScheme getScheme() {
        return new system_drop_column_family_argsStandardScheme();
      }
    }

    private static class system_drop_column_family_argsStandardScheme extends StandardScheme<system_drop_column_family_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_drop_column_family_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: // COLUMN_FAMILY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.column_family = iprot.readString();
                struct.setColumn_familyIsSet(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, system_drop_column_family_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.column_family != null) {
          oprot.writeFieldBegin(COLUMN_FAMILY_FIELD_DESC);
          oprot.writeString(struct.column_family);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_drop_column_family_argsTupleSchemeFactory implements SchemeFactory {
      public system_drop_column_family_argsTupleScheme getScheme() {
        return new system_drop_column_family_argsTupleScheme();
      }
    }

    private static class system_drop_column_family_argsTupleScheme extends TupleScheme<system_drop_column_family_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_drop_column_family_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.column_family);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_drop_column_family_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.column_family = iprot.readString();
        struct.setColumn_familyIsSet(true);
      }
    }

  }

  public static class system_drop_column_family_result implements org.apache.thrift.TBase<system_drop_column_family_result, system_drop_column_family_result._Fields>, java.io.Serializable, Cloneable, Comparable<system_drop_column_family_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_drop_column_family_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", 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 system_drop_column_family_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_drop_column_family_resultTupleSchemeFactory());
    }

    public String success; // required
    public InvalidRequestException ire; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      SDE((short)2, "sde");

      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: // IRE
            return IRE;
          case 2: // SDE
            return SDE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(system_drop_column_family_result.class, metaDataMap);
    }

    public system_drop_column_family_result() {
    }

    public system_drop_column_family_result(
      String success,
      InvalidRequestException ire,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_drop_column_family_result(system_drop_column_family_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public system_drop_column_family_result deepCopy() {
      return new system_drop_column_family_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.sde = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public system_drop_column_family_result setSuccess(String 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public system_drop_column_family_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public system_drop_column_family_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_drop_column_family_result)
        return this.equals((system_drop_column_family_result)that);
      return false;
    }

    public boolean equals(system_drop_column_family_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_drop_column_family_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("system_drop_column_family_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 system_drop_column_family_resultStandardSchemeFactory implements SchemeFactory {
      public system_drop_column_family_resultStandardScheme getScheme() {
        return new system_drop_column_family_resultStandardScheme();
      }
    }

    private static class system_drop_column_family_resultStandardScheme extends StandardScheme<system_drop_column_family_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_drop_column_family_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, system_drop_column_family_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_drop_column_family_resultTupleSchemeFactory implements SchemeFactory {
      public system_drop_column_family_resultTupleScheme getScheme() {
        return new system_drop_column_family_resultTupleScheme();
      }
    }

    private static class system_drop_column_family_resultTupleScheme extends TupleScheme<system_drop_column_family_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_drop_column_family_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetSde()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_drop_column_family_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class system_add_keyspace_args implements org.apache.thrift.TBase<system_add_keyspace_args, system_add_keyspace_args._Fields>, java.io.Serializable, Cloneable, Comparable<system_add_keyspace_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_add_keyspace_args");

    private static final org.apache.thrift.protocol.TField KS_DEF_FIELD_DESC = new org.apache.thrift.protocol.TField("ks_def", 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 system_add_keyspace_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_add_keyspace_argsTupleSchemeFactory());
    }

    public KsDef ks_def; // 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 {
      KS_DEF((short)1, "ks_def");

      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: // KS_DEF
            return KS_DEF;
          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.KS_DEF, new org.apache.thrift.meta_data.FieldMetaData("ks_def", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KsDef.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(system_add_keyspace_args.class, metaDataMap);
    }

    public system_add_keyspace_args() {
    }

    public system_add_keyspace_args(
      KsDef ks_def)
    {
      this();
      this.ks_def = ks_def;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_add_keyspace_args(system_add_keyspace_args other) {
      if (other.isSetKs_def()) {
        this.ks_def = new KsDef(other.ks_def);
      }
    }

    public system_add_keyspace_args deepCopy() {
      return new system_add_keyspace_args(this);
    }

    @Override
    public void clear() {
      this.ks_def = null;
    }

    public KsDef getKs_def() {
      return this.ks_def;
    }

    public system_add_keyspace_args setKs_def(KsDef ks_def) {
      this.ks_def = ks_def;
      return this;
    }

    public void unsetKs_def() {
      this.ks_def = null;
    }

    /** Returns true if field ks_def is set (has been assigned a value) and false otherwise */
    public boolean isSetKs_def() {
      return this.ks_def != null;
    }

    public void setKs_defIsSet(boolean value) {
      if (!value) {
        this.ks_def = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KS_DEF:
        if (value == null) {
          unsetKs_def();
        } else {
          setKs_def((KsDef)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KS_DEF:
        return getKs_def();

      }
      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 KS_DEF:
        return isSetKs_def();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_add_keyspace_args)
        return this.equals((system_add_keyspace_args)that);
      return false;
    }

    public boolean equals(system_add_keyspace_args that) {
      if (that == null)
        return false;

      boolean this_present_ks_def = true && this.isSetKs_def();
      boolean that_present_ks_def = true && that.isSetKs_def();
      if (this_present_ks_def || that_present_ks_def) {
        if (!(this_present_ks_def && that_present_ks_def))
          return false;
        if (!this.ks_def.equals(that.ks_def))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ks_def = true && (isSetKs_def());
      builder.append(present_ks_def);
      if (present_ks_def)
        builder.append(ks_def);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_add_keyspace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKs_def()).compareTo(other.isSetKs_def());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKs_def()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ks_def, other.ks_def);
        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("system_add_keyspace_args(");
      boolean first = true;

      sb.append("ks_def:");
      if (this.ks_def == null) {
        sb.append("null");
      } else {
        sb.append(this.ks_def);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (ks_def == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'ks_def' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (ks_def != null) {
        ks_def.validate();
      }
    }

    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 system_add_keyspace_argsStandardSchemeFactory implements SchemeFactory {
      public system_add_keyspace_argsStandardScheme getScheme() {
        return new system_add_keyspace_argsStandardScheme();
      }
    }

    private static class system_add_keyspace_argsStandardScheme extends StandardScheme<system_add_keyspace_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_add_keyspace_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: // KS_DEF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ks_def = new KsDef();
                struct.ks_def.read(iprot);
                struct.setKs_defIsSet(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, system_add_keyspace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ks_def != null) {
          oprot.writeFieldBegin(KS_DEF_FIELD_DESC);
          struct.ks_def.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_add_keyspace_argsTupleSchemeFactory implements SchemeFactory {
      public system_add_keyspace_argsTupleScheme getScheme() {
        return new system_add_keyspace_argsTupleScheme();
      }
    }

    private static class system_add_keyspace_argsTupleScheme extends TupleScheme<system_add_keyspace_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_add_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.ks_def.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_add_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.ks_def = new KsDef();
        struct.ks_def.read(iprot);
        struct.setKs_defIsSet(true);
      }
    }

  }

  public static class system_add_keyspace_result implements org.apache.thrift.TBase<system_add_keyspace_result, system_add_keyspace_result._Fields>, java.io.Serializable, Cloneable, Comparable<system_add_keyspace_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_add_keyspace_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", 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 system_add_keyspace_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_add_keyspace_resultTupleSchemeFactory());
    }

    public String success; // required
    public InvalidRequestException ire; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      SDE((short)2, "sde");

      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: // IRE
            return IRE;
          case 2: // SDE
            return SDE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(system_add_keyspace_result.class, metaDataMap);
    }

    public system_add_keyspace_result() {
    }

    public system_add_keyspace_result(
      String success,
      InvalidRequestException ire,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_add_keyspace_result(system_add_keyspace_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public system_add_keyspace_result deepCopy() {
      return new system_add_keyspace_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.sde = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public system_add_keyspace_result setSuccess(String 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public system_add_keyspace_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public system_add_keyspace_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_add_keyspace_result)
        return this.equals((system_add_keyspace_result)that);
      return false;
    }

    public boolean equals(system_add_keyspace_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_add_keyspace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("system_add_keyspace_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 system_add_keyspace_resultStandardSchemeFactory implements SchemeFactory {
      public system_add_keyspace_resultStandardScheme getScheme() {
        return new system_add_keyspace_resultStandardScheme();
      }
    }

    private static class system_add_keyspace_resultStandardScheme extends StandardScheme<system_add_keyspace_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_add_keyspace_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, system_add_keyspace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_add_keyspace_resultTupleSchemeFactory implements SchemeFactory {
      public system_add_keyspace_resultTupleScheme getScheme() {
        return new system_add_keyspace_resultTupleScheme();
      }
    }

    private static class system_add_keyspace_resultTupleScheme extends TupleScheme<system_add_keyspace_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_add_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetSde()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_add_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class system_drop_keyspace_args implements org.apache.thrift.TBase<system_drop_keyspace_args, system_drop_keyspace_args._Fields>, java.io.Serializable, Cloneable, Comparable<system_drop_keyspace_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_drop_keyspace_args");

    private static final org.apache.thrift.protocol.TField KEYSPACE_FIELD_DESC = new org.apache.thrift.protocol.TField("keyspace", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new system_drop_keyspace_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_drop_keyspace_argsTupleSchemeFactory());
    }

    public String keyspace; // 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 {
      KEYSPACE((short)1, "keyspace");

      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: // KEYSPACE
            return KEYSPACE;
          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.KEYSPACE, new org.apache.thrift.meta_data.FieldMetaData("keyspace", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(system_drop_keyspace_args.class, metaDataMap);
    }

    public system_drop_keyspace_args() {
    }

    public system_drop_keyspace_args(
      String keyspace)
    {
      this();
      this.keyspace = keyspace;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_drop_keyspace_args(system_drop_keyspace_args other) {
      if (other.isSetKeyspace()) {
        this.keyspace = other.keyspace;
      }
    }

    public system_drop_keyspace_args deepCopy() {
      return new system_drop_keyspace_args(this);
    }

    @Override
    public void clear() {
      this.keyspace = null;
    }

    public String getKeyspace() {
      return this.keyspace;
    }

    public system_drop_keyspace_args setKeyspace(String keyspace) {
      this.keyspace = keyspace;
      return this;
    }

    public void unsetKeyspace() {
      this.keyspace = null;
    }

    /** Returns true if field keyspace is set (has been assigned a value) and false otherwise */
    public boolean isSetKeyspace() {
      return this.keyspace != null;
    }

    public void setKeyspaceIsSet(boolean value) {
      if (!value) {
        this.keyspace = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KEYSPACE:
        if (value == null) {
          unsetKeyspace();
        } else {
          setKeyspace((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KEYSPACE:
        return getKeyspace();

      }
      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 KEYSPACE:
        return isSetKeyspace();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_drop_keyspace_args)
        return this.equals((system_drop_keyspace_args)that);
      return false;
    }

    public boolean equals(system_drop_keyspace_args that) {
      if (that == null)
        return false;

      boolean this_present_keyspace = true && this.isSetKeyspace();
      boolean that_present_keyspace = true && that.isSetKeyspace();
      if (this_present_keyspace || that_present_keyspace) {
        if (!(this_present_keyspace && that_present_keyspace))
          return false;
        if (!this.keyspace.equals(that.keyspace))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_keyspace = true && (isSetKeyspace());
      builder.append(present_keyspace);
      if (present_keyspace)
        builder.append(keyspace);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_drop_keyspace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKeyspace()).compareTo(other.isSetKeyspace());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKeyspace()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyspace, other.keyspace);
        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("system_drop_keyspace_args(");
      boolean first = true;

      sb.append("keyspace:");
      if (this.keyspace == null) {
        sb.append("null");
      } else {
        sb.append(this.keyspace);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (keyspace == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'keyspace' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 system_drop_keyspace_argsStandardSchemeFactory implements SchemeFactory {
      public system_drop_keyspace_argsStandardScheme getScheme() {
        return new system_drop_keyspace_argsStandardScheme();
      }
    }

    private static class system_drop_keyspace_argsStandardScheme extends StandardScheme<system_drop_keyspace_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_drop_keyspace_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: // KEYSPACE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.keyspace = iprot.readString();
                struct.setKeyspaceIsSet(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, system_drop_keyspace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.keyspace != null) {
          oprot.writeFieldBegin(KEYSPACE_FIELD_DESC);
          oprot.writeString(struct.keyspace);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_drop_keyspace_argsTupleSchemeFactory implements SchemeFactory {
      public system_drop_keyspace_argsTupleScheme getScheme() {
        return new system_drop_keyspace_argsTupleScheme();
      }
    }

    private static class system_drop_keyspace_argsTupleScheme extends TupleScheme<system_drop_keyspace_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_drop_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.keyspace);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_drop_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.keyspace = iprot.readString();
        struct.setKeyspaceIsSet(true);
      }
    }

  }

  public static class system_drop_keyspace_result implements org.apache.thrift.TBase<system_drop_keyspace_result, system_drop_keyspace_result._Fields>, java.io.Serializable, Cloneable, Comparable<system_drop_keyspace_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_drop_keyspace_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", 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 system_drop_keyspace_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_drop_keyspace_resultTupleSchemeFactory());
    }

    public String success; // required
    public InvalidRequestException ire; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      SDE((short)2, "sde");

      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: // IRE
            return IRE;
          case 2: // SDE
            return SDE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(system_drop_keyspace_result.class, metaDataMap);
    }

    public system_drop_keyspace_result() {
    }

    public system_drop_keyspace_result(
      String success,
      InvalidRequestException ire,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_drop_keyspace_result(system_drop_keyspace_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public system_drop_keyspace_result deepCopy() {
      return new system_drop_keyspace_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.sde = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public system_drop_keyspace_result setSuccess(String 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public system_drop_keyspace_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public system_drop_keyspace_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_drop_keyspace_result)
        return this.equals((system_drop_keyspace_result)that);
      return false;
    }

    public boolean equals(system_drop_keyspace_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_drop_keyspace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("system_drop_keyspace_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 system_drop_keyspace_resultStandardSchemeFactory implements SchemeFactory {
      public system_drop_keyspace_resultStandardScheme getScheme() {
        return new system_drop_keyspace_resultStandardScheme();
      }
    }

    private static class system_drop_keyspace_resultStandardScheme extends StandardScheme<system_drop_keyspace_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_drop_keyspace_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, system_drop_keyspace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_drop_keyspace_resultTupleSchemeFactory implements SchemeFactory {
      public system_drop_keyspace_resultTupleScheme getScheme() {
        return new system_drop_keyspace_resultTupleScheme();
      }
    }

    private static class system_drop_keyspace_resultTupleScheme extends TupleScheme<system_drop_keyspace_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_drop_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetSde()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_drop_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class system_update_keyspace_args implements org.apache.thrift.TBase<system_update_keyspace_args, system_update_keyspace_args._Fields>, java.io.Serializable, Cloneable, Comparable<system_update_keyspace_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_update_keyspace_args");

    private static final org.apache.thrift.protocol.TField KS_DEF_FIELD_DESC = new org.apache.thrift.protocol.TField("ks_def", 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 system_update_keyspace_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_update_keyspace_argsTupleSchemeFactory());
    }

    public KsDef ks_def; // 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 {
      KS_DEF((short)1, "ks_def");

      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: // KS_DEF
            return KS_DEF;
          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.KS_DEF, new org.apache.thrift.meta_data.FieldMetaData("ks_def", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KsDef.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(system_update_keyspace_args.class, metaDataMap);
    }

    public system_update_keyspace_args() {
    }

    public system_update_keyspace_args(
      KsDef ks_def)
    {
      this();
      this.ks_def = ks_def;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_update_keyspace_args(system_update_keyspace_args other) {
      if (other.isSetKs_def()) {
        this.ks_def = new KsDef(other.ks_def);
      }
    }

    public system_update_keyspace_args deepCopy() {
      return new system_update_keyspace_args(this);
    }

    @Override
    public void clear() {
      this.ks_def = null;
    }

    public KsDef getKs_def() {
      return this.ks_def;
    }

    public system_update_keyspace_args setKs_def(KsDef ks_def) {
      this.ks_def = ks_def;
      return this;
    }

    public void unsetKs_def() {
      this.ks_def = null;
    }

    /** Returns true if field ks_def is set (has been assigned a value) and false otherwise */
    public boolean isSetKs_def() {
      return this.ks_def != null;
    }

    public void setKs_defIsSet(boolean value) {
      if (!value) {
        this.ks_def = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case KS_DEF:
        if (value == null) {
          unsetKs_def();
        } else {
          setKs_def((KsDef)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case KS_DEF:
        return getKs_def();

      }
      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 KS_DEF:
        return isSetKs_def();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_update_keyspace_args)
        return this.equals((system_update_keyspace_args)that);
      return false;
    }

    public boolean equals(system_update_keyspace_args that) {
      if (that == null)
        return false;

      boolean this_present_ks_def = true && this.isSetKs_def();
      boolean that_present_ks_def = true && that.isSetKs_def();
      if (this_present_ks_def || that_present_ks_def) {
        if (!(this_present_ks_def && that_present_ks_def))
          return false;
        if (!this.ks_def.equals(that.ks_def))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ks_def = true && (isSetKs_def());
      builder.append(present_ks_def);
      if (present_ks_def)
        builder.append(ks_def);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_update_keyspace_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetKs_def()).compareTo(other.isSetKs_def());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetKs_def()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ks_def, other.ks_def);
        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("system_update_keyspace_args(");
      boolean first = true;

      sb.append("ks_def:");
      if (this.ks_def == null) {
        sb.append("null");
      } else {
        sb.append(this.ks_def);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (ks_def == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'ks_def' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (ks_def != null) {
        ks_def.validate();
      }
    }

    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 system_update_keyspace_argsStandardSchemeFactory implements SchemeFactory {
      public system_update_keyspace_argsStandardScheme getScheme() {
        return new system_update_keyspace_argsStandardScheme();
      }
    }

    private static class system_update_keyspace_argsStandardScheme extends StandardScheme<system_update_keyspace_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_update_keyspace_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: // KS_DEF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ks_def = new KsDef();
                struct.ks_def.read(iprot);
                struct.setKs_defIsSet(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, system_update_keyspace_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ks_def != null) {
          oprot.writeFieldBegin(KS_DEF_FIELD_DESC);
          struct.ks_def.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_update_keyspace_argsTupleSchemeFactory implements SchemeFactory {
      public system_update_keyspace_argsTupleScheme getScheme() {
        return new system_update_keyspace_argsTupleScheme();
      }
    }

    private static class system_update_keyspace_argsTupleScheme extends TupleScheme<system_update_keyspace_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_update_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.ks_def.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_update_keyspace_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.ks_def = new KsDef();
        struct.ks_def.read(iprot);
        struct.setKs_defIsSet(true);
      }
    }

  }

  public static class system_update_keyspace_result implements org.apache.thrift.TBase<system_update_keyspace_result, system_update_keyspace_result._Fields>, java.io.Serializable, Cloneable, Comparable<system_update_keyspace_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_update_keyspace_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", 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 system_update_keyspace_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_update_keyspace_resultTupleSchemeFactory());
    }

    public String success; // required
    public InvalidRequestException ire; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      SDE((short)2, "sde");

      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: // IRE
            return IRE;
          case 2: // SDE
            return SDE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(system_update_keyspace_result.class, metaDataMap);
    }

    public system_update_keyspace_result() {
    }

    public system_update_keyspace_result(
      String success,
      InvalidRequestException ire,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_update_keyspace_result(system_update_keyspace_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public system_update_keyspace_result deepCopy() {
      return new system_update_keyspace_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.sde = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public system_update_keyspace_result setSuccess(String 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public system_update_keyspace_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public system_update_keyspace_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_update_keyspace_result)
        return this.equals((system_update_keyspace_result)that);
      return false;
    }

    public boolean equals(system_update_keyspace_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_update_keyspace_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("system_update_keyspace_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 system_update_keyspace_resultStandardSchemeFactory implements SchemeFactory {
      public system_update_keyspace_resultStandardScheme getScheme() {
        return new system_update_keyspace_resultStandardScheme();
      }
    }

    private static class system_update_keyspace_resultStandardScheme extends StandardScheme<system_update_keyspace_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_update_keyspace_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, system_update_keyspace_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_update_keyspace_resultTupleSchemeFactory implements SchemeFactory {
      public system_update_keyspace_resultTupleScheme getScheme() {
        return new system_update_keyspace_resultTupleScheme();
      }
    }

    private static class system_update_keyspace_resultTupleScheme extends TupleScheme<system_update_keyspace_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_update_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetSde()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_update_keyspace_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class system_update_column_family_args implements org.apache.thrift.TBase<system_update_column_family_args, system_update_column_family_args._Fields>, java.io.Serializable, Cloneable, Comparable<system_update_column_family_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_update_column_family_args");

    private static final org.apache.thrift.protocol.TField CF_DEF_FIELD_DESC = new org.apache.thrift.protocol.TField("cf_def", 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 system_update_column_family_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_update_column_family_argsTupleSchemeFactory());
    }

    public CfDef cf_def; // 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 {
      CF_DEF((short)1, "cf_def");

      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: // CF_DEF
            return CF_DEF;
          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.CF_DEF, new org.apache.thrift.meta_data.FieldMetaData("cf_def", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CfDef.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(system_update_column_family_args.class, metaDataMap);
    }

    public system_update_column_family_args() {
    }

    public system_update_column_family_args(
      CfDef cf_def)
    {
      this();
      this.cf_def = cf_def;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_update_column_family_args(system_update_column_family_args other) {
      if (other.isSetCf_def()) {
        this.cf_def = new CfDef(other.cf_def);
      }
    }

    public system_update_column_family_args deepCopy() {
      return new system_update_column_family_args(this);
    }

    @Override
    public void clear() {
      this.cf_def = null;
    }

    public CfDef getCf_def() {
      return this.cf_def;
    }

    public system_update_column_family_args setCf_def(CfDef cf_def) {
      this.cf_def = cf_def;
      return this;
    }

    public void unsetCf_def() {
      this.cf_def = null;
    }

    /** Returns true if field cf_def is set (has been assigned a value) and false otherwise */
    public boolean isSetCf_def() {
      return this.cf_def != null;
    }

    public void setCf_defIsSet(boolean value) {
      if (!value) {
        this.cf_def = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case CF_DEF:
        if (value == null) {
          unsetCf_def();
        } else {
          setCf_def((CfDef)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case CF_DEF:
        return getCf_def();

      }
      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 CF_DEF:
        return isSetCf_def();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_update_column_family_args)
        return this.equals((system_update_column_family_args)that);
      return false;
    }

    public boolean equals(system_update_column_family_args that) {
      if (that == null)
        return false;

      boolean this_present_cf_def = true && this.isSetCf_def();
      boolean that_present_cf_def = true && that.isSetCf_def();
      if (this_present_cf_def || that_present_cf_def) {
        if (!(this_present_cf_def && that_present_cf_def))
          return false;
        if (!this.cf_def.equals(that.cf_def))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_cf_def = true && (isSetCf_def());
      builder.append(present_cf_def);
      if (present_cf_def)
        builder.append(cf_def);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_update_column_family_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetCf_def()).compareTo(other.isSetCf_def());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCf_def()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cf_def, other.cf_def);
        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("system_update_column_family_args(");
      boolean first = true;

      sb.append("cf_def:");
      if (this.cf_def == null) {
        sb.append("null");
      } else {
        sb.append(this.cf_def);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (cf_def == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'cf_def' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (cf_def != null) {
        cf_def.validate();
      }
    }

    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 system_update_column_family_argsStandardSchemeFactory implements SchemeFactory {
      public system_update_column_family_argsStandardScheme getScheme() {
        return new system_update_column_family_argsStandardScheme();
      }
    }

    private static class system_update_column_family_argsStandardScheme extends StandardScheme<system_update_column_family_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_update_column_family_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: // CF_DEF
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.cf_def = new CfDef();
                struct.cf_def.read(iprot);
                struct.setCf_defIsSet(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, system_update_column_family_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.cf_def != null) {
          oprot.writeFieldBegin(CF_DEF_FIELD_DESC);
          struct.cf_def.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_update_column_family_argsTupleSchemeFactory implements SchemeFactory {
      public system_update_column_family_argsTupleScheme getScheme() {
        return new system_update_column_family_argsTupleScheme();
      }
    }

    private static class system_update_column_family_argsTupleScheme extends TupleScheme<system_update_column_family_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_update_column_family_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        struct.cf_def.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_update_column_family_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.cf_def = new CfDef();
        struct.cf_def.read(iprot);
        struct.setCf_defIsSet(true);
      }
    }

  }

  public static class system_update_column_family_result implements org.apache.thrift.TBase<system_update_column_family_result, system_update_column_family_result._Fields>, java.io.Serializable, Cloneable, Comparable<system_update_column_family_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("system_update_column_family_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", 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 system_update_column_family_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new system_update_column_family_resultTupleSchemeFactory());
    }

    public String success; // required
    public InvalidRequestException ire; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      SDE((short)2, "sde");

      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: // IRE
            return IRE;
          case 2: // SDE
            return SDE;
          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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(system_update_column_family_result.class, metaDataMap);
    }

    public system_update_column_family_result() {
    }

    public system_update_column_family_result(
      String success,
      InvalidRequestException ire,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public system_update_column_family_result(system_update_column_family_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public system_update_column_family_result deepCopy() {
      return new system_update_column_family_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.sde = null;
    }

    public String getSuccess() {
      return this.success;
    }

    public system_update_column_family_result setSuccess(String 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public system_update_column_family_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public system_update_column_family_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((String)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof system_update_column_family_result)
        return this.equals((system_update_column_family_result)that);
      return false;
    }

    public boolean equals(system_update_column_family_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(system_update_column_family_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("system_update_column_family_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 system_update_column_family_resultStandardSchemeFactory implements SchemeFactory {
      public system_update_column_family_resultStandardScheme getScheme() {
        return new system_update_column_family_resultStandardScheme();
      }
    }

    private static class system_update_column_family_resultStandardScheme extends StandardScheme<system_update_column_family_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, system_update_column_family_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.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, system_update_column_family_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class system_update_column_family_resultTupleSchemeFactory implements SchemeFactory {
      public system_update_column_family_resultTupleScheme getScheme() {
        return new system_update_column_family_resultTupleScheme();
      }
    }

    private static class system_update_column_family_resultTupleScheme extends TupleScheme<system_update_column_family_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, system_update_column_family_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetSde()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, system_update_column_family_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class execute_cql_query_args implements org.apache.thrift.TBase<execute_cql_query_args, execute_cql_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<execute_cql_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_cql_query_args");

    private static final org.apache.thrift.protocol.TField QUERY_FIELD_DESC = new org.apache.thrift.protocol.TField("query", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COMPRESSION_FIELD_DESC = new org.apache.thrift.protocol.TField("compression", 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 execute_cql_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_cql_query_argsTupleSchemeFactory());
    }

    public ByteBuffer query; // required
    /**
     * 
     * @see Compression
     */
    public Compression compression; // 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 {
      QUERY((short)1, "query"),
      /**
       * 
       * @see Compression
       */
      COMPRESSION((short)2, "compression");

      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: // QUERY
            return QUERY;
          case 2: // COMPRESSION
            return COMPRESSION;
          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.QUERY, new org.apache.thrift.meta_data.FieldMetaData("query", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COMPRESSION, new org.apache.thrift.meta_data.FieldMetaData("compression", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Compression.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(execute_cql_query_args.class, metaDataMap);
    }

    public execute_cql_query_args() {
    }

    public execute_cql_query_args(
      ByteBuffer query,
      Compression compression)
    {
      this();
      this.query = query;
      this.compression = compression;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_cql_query_args(execute_cql_query_args other) {
      if (other.isSetQuery()) {
        this.query = org.apache.thrift.TBaseHelper.copyBinary(other.query);
;
      }
      if (other.isSetCompression()) {
        this.compression = other.compression;
      }
    }

    public execute_cql_query_args deepCopy() {
      return new execute_cql_query_args(this);
    }

    @Override
    public void clear() {
      this.query = null;
      this.compression = null;
    }

    public byte[] getQuery() {
      setQuery(org.apache.thrift.TBaseHelper.rightSize(query));
      return query == null ? null : query.array();
    }

    public ByteBuffer bufferForQuery() {
      return query;
    }

    public execute_cql_query_args setQuery(byte[] query) {
      setQuery(query == null ? (ByteBuffer)null : ByteBuffer.wrap(query));
      return this;
    }

    public execute_cql_query_args setQuery(ByteBuffer query) {
      this.query = query;
      return this;
    }

    public void unsetQuery() {
      this.query = null;
    }

    /** Returns true if field query is set (has been assigned a value) and false otherwise */
    public boolean isSetQuery() {
      return this.query != null;
    }

    public void setQueryIsSet(boolean value) {
      if (!value) {
        this.query = null;
      }
    }

    /**
     * 
     * @see Compression
     */
    public Compression getCompression() {
      return this.compression;
    }

    /**
     * 
     * @see Compression
     */
    public execute_cql_query_args setCompression(Compression compression) {
      this.compression = compression;
      return this;
    }

    public void unsetCompression() {
      this.compression = null;
    }

    /** Returns true if field compression is set (has been assigned a value) and false otherwise */
    public boolean isSetCompression() {
      return this.compression != null;
    }

    public void setCompressionIsSet(boolean value) {
      if (!value) {
        this.compression = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case QUERY:
        if (value == null) {
          unsetQuery();
        } else {
          setQuery((ByteBuffer)value);
        }
        break;

      case COMPRESSION:
        if (value == null) {
          unsetCompression();
        } else {
          setCompression((Compression)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case QUERY:
        return getQuery();

      case COMPRESSION:
        return getCompression();

      }
      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 QUERY:
        return isSetQuery();
      case COMPRESSION:
        return isSetCompression();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_cql_query_args)
        return this.equals((execute_cql_query_args)that);
      return false;
    }

    public boolean equals(execute_cql_query_args that) {
      if (that == null)
        return false;

      boolean this_present_query = true && this.isSetQuery();
      boolean that_present_query = true && that.isSetQuery();
      if (this_present_query || that_present_query) {
        if (!(this_present_query && that_present_query))
          return false;
        if (!this.query.equals(that.query))
          return false;
      }

      boolean this_present_compression = true && this.isSetCompression();
      boolean that_present_compression = true && that.isSetCompression();
      if (this_present_compression || that_present_compression) {
        if (!(this_present_compression && that_present_compression))
          return false;
        if (!this.compression.equals(that.compression))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_query = true && (isSetQuery());
      builder.append(present_query);
      if (present_query)
        builder.append(query);

      boolean present_compression = true && (isSetCompression());
      builder.append(present_compression);
      if (present_compression)
        builder.append(compression.getValue());

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_cql_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetQuery()).compareTo(other.isSetQuery());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQuery()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.query, other.query);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetCompression()).compareTo(other.isSetCompression());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCompression()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.compression, other.compression);
        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("execute_cql_query_args(");
      boolean first = true;

      sb.append("query:");
      if (this.query == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.query, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("compression:");
      if (this.compression == null) {
        sb.append("null");
      } else {
        sb.append(this.compression);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (query == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'query' was not present! Struct: " + toString());
      }
      if (compression == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'compression' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 execute_cql_query_argsStandardSchemeFactory implements SchemeFactory {
      public execute_cql_query_argsStandardScheme getScheme() {
        return new execute_cql_query_argsStandardScheme();
      }
    }

    private static class execute_cql_query_argsStandardScheme extends StandardScheme<execute_cql_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_cql_query_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: // QUERY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.query = iprot.readBinary();
                struct.setQueryIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COMPRESSION
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.compression = Compression.findByValue(iprot.readI32());
                struct.setCompressionIsSet(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, execute_cql_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.query != null) {
          oprot.writeFieldBegin(QUERY_FIELD_DESC);
          oprot.writeBinary(struct.query);
          oprot.writeFieldEnd();
        }
        if (struct.compression != null) {
          oprot.writeFieldBegin(COMPRESSION_FIELD_DESC);
          oprot.writeI32(struct.compression.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_cql_query_argsTupleSchemeFactory implements SchemeFactory {
      public execute_cql_query_argsTupleScheme getScheme() {
        return new execute_cql_query_argsTupleScheme();
      }
    }

    private static class execute_cql_query_argsTupleScheme extends TupleScheme<execute_cql_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_cql_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.query);
        oprot.writeI32(struct.compression.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_cql_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.query = iprot.readBinary();
        struct.setQueryIsSet(true);
        struct.compression = Compression.findByValue(iprot.readI32());
        struct.setCompressionIsSet(true);
      }
    }

  }

  public static class execute_cql_query_result implements org.apache.thrift.TBase<execute_cql_query_result, execute_cql_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<execute_cql_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_cql_query_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_cql_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_cql_query_resultTupleSchemeFactory());
    }

    public CqlResult success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te"),
      SDE((short)4, "sde");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          case 4: // SDE
            return SDE;
          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, CqlResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(execute_cql_query_result.class, metaDataMap);
    }

    public execute_cql_query_result() {
    }

    public execute_cql_query_result(
      CqlResult success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_cql_query_result(execute_cql_query_result other) {
      if (other.isSetSuccess()) {
        this.success = new CqlResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public execute_cql_query_result deepCopy() {
      return new execute_cql_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
      this.sde = null;
    }

    public CqlResult getSuccess() {
      return this.success;
    }

    public execute_cql_query_result setSuccess(CqlResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public execute_cql_query_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public UnavailableException getUe() {
      return this.ue;
    }

    public execute_cql_query_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

    /** Returns true if field ue is set (has been assigned a value) and false otherwise */
    public boolean isSetUe() {
      return this.ue != null;
    }

    public void setUeIsSet(boolean value) {
      if (!value) {
        this.ue = null;
      }
    }

    public TimedOutException getTe() {
      return this.te;
    }

    public execute_cql_query_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

    /** Returns true if field te is set (has been assigned a value) and false otherwise */
    public boolean isSetTe() {
      return this.te != null;
    }

    public void setTeIsSet(boolean value) {
      if (!value) {
        this.te = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public execute_cql_query_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((CqlResult)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_cql_query_result)
        return this.equals((execute_cql_query_result)that);
      return false;
    }

    public boolean equals(execute_cql_query_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_cql_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("execute_cql_query_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 execute_cql_query_resultStandardSchemeFactory implements SchemeFactory {
      public execute_cql_query_resultStandardScheme getScheme() {
        return new execute_cql_query_resultStandardScheme();
      }
    }

    private static class execute_cql_query_resultStandardScheme extends StandardScheme<execute_cql_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_cql_query_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 CqlResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, execute_cql_query_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_cql_query_resultTupleSchemeFactory implements SchemeFactory {
      public execute_cql_query_resultTupleScheme getScheme() {
        return new execute_cql_query_resultTupleScheme();
      }
    }

    private static class execute_cql_query_resultTupleScheme extends TupleScheme<execute_cql_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_cql_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        if (struct.isSetSde()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_cql_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new CqlResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
        if (incoming.get(4)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class execute_cql3_query_args implements org.apache.thrift.TBase<execute_cql3_query_args, execute_cql3_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<execute_cql3_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_cql3_query_args");

    private static final org.apache.thrift.protocol.TField QUERY_FIELD_DESC = new org.apache.thrift.protocol.TField("query", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COMPRESSION_FIELD_DESC = new org.apache.thrift.protocol.TField("compression", org.apache.thrift.protocol.TType.I32, (short)2);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_cql3_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_cql3_query_argsTupleSchemeFactory());
    }

    public ByteBuffer query; // required
    /**
     * 
     * @see Compression
     */
    public Compression compression; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency; // 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 {
      QUERY((short)1, "query"),
      /**
       * 
       * @see Compression
       */
      COMPRESSION((short)2, "compression"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY((short)3, "consistency");

      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: // QUERY
            return QUERY;
          case 2: // COMPRESSION
            return COMPRESSION;
          case 3: // CONSISTENCY
            return CONSISTENCY;
          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.QUERY, new org.apache.thrift.meta_data.FieldMetaData("query", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COMPRESSION, new org.apache.thrift.meta_data.FieldMetaData("compression", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Compression.class)));
      tmpMap.put(_Fields.CONSISTENCY, new org.apache.thrift.meta_data.FieldMetaData("consistency", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(execute_cql3_query_args.class, metaDataMap);
    }

    public execute_cql3_query_args() {
    }

    public execute_cql3_query_args(
      ByteBuffer query,
      Compression compression,
      ConsistencyLevel consistency)
    {
      this();
      this.query = query;
      this.compression = compression;
      this.consistency = consistency;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_cql3_query_args(execute_cql3_query_args other) {
      if (other.isSetQuery()) {
        this.query = org.apache.thrift.TBaseHelper.copyBinary(other.query);
;
      }
      if (other.isSetCompression()) {
        this.compression = other.compression;
      }
      if (other.isSetConsistency()) {
        this.consistency = other.consistency;
      }
    }

    public execute_cql3_query_args deepCopy() {
      return new execute_cql3_query_args(this);
    }

    @Override
    public void clear() {
      this.query = null;
      this.compression = null;
      this.consistency = null;
    }

    public byte[] getQuery() {
      setQuery(org.apache.thrift.TBaseHelper.rightSize(query));
      return query == null ? null : query.array();
    }

    public ByteBuffer bufferForQuery() {
      return query;
    }

    public execute_cql3_query_args setQuery(byte[] query) {
      setQuery(query == null ? (ByteBuffer)null : ByteBuffer.wrap(query));
      return this;
    }

    public execute_cql3_query_args setQuery(ByteBuffer query) {
      this.query = query;
      return this;
    }

    public void unsetQuery() {
      this.query = null;
    }

    /** Returns true if field query is set (has been assigned a value) and false otherwise */
    public boolean isSetQuery() {
      return this.query != null;
    }

    public void setQueryIsSet(boolean value) {
      if (!value) {
        this.query = null;
      }
    }

    /**
     * 
     * @see Compression
     */
    public Compression getCompression() {
      return this.compression;
    }

    /**
     * 
     * @see Compression
     */
    public execute_cql3_query_args setCompression(Compression compression) {
      this.compression = compression;
      return this;
    }

    public void unsetCompression() {
      this.compression = null;
    }

    /** Returns true if field compression is set (has been assigned a value) and false otherwise */
    public boolean isSetCompression() {
      return this.compression != null;
    }

    public void setCompressionIsSet(boolean value) {
      if (!value) {
        this.compression = null;
      }
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency() {
      return this.consistency;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public execute_cql3_query_args setConsistency(ConsistencyLevel consistency) {
      this.consistency = consistency;
      return this;
    }

    public void unsetConsistency() {
      this.consistency = null;
    }

    /** Returns true if field consistency is set (has been assigned a value) and false otherwise */
    public boolean isSetConsistency() {
      return this.consistency != null;
    }

    public void setConsistencyIsSet(boolean value) {
      if (!value) {
        this.consistency = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case QUERY:
        if (value == null) {
          unsetQuery();
        } else {
          setQuery((ByteBuffer)value);
        }
        break;

      case COMPRESSION:
        if (value == null) {
          unsetCompression();
        } else {
          setCompression((Compression)value);
        }
        break;

      case CONSISTENCY:
        if (value == null) {
          unsetConsistency();
        } else {
          setConsistency((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case QUERY:
        return getQuery();

      case COMPRESSION:
        return getCompression();

      case CONSISTENCY:
        return getConsistency();

      }
      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 QUERY:
        return isSetQuery();
      case COMPRESSION:
        return isSetCompression();
      case CONSISTENCY:
        return isSetConsistency();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_cql3_query_args)
        return this.equals((execute_cql3_query_args)that);
      return false;
    }

    public boolean equals(execute_cql3_query_args that) {
      if (that == null)
        return false;

      boolean this_present_query = true && this.isSetQuery();
      boolean that_present_query = true && that.isSetQuery();
      if (this_present_query || that_present_query) {
        if (!(this_present_query && that_present_query))
          return false;
        if (!this.query.equals(that.query))
          return false;
      }

      boolean this_present_compression = true && this.isSetCompression();
      boolean that_present_compression = true && that.isSetCompression();
      if (this_present_compression || that_present_compression) {
        if (!(this_present_compression && that_present_compression))
          return false;
        if (!this.compression.equals(that.compression))
          return false;
      }

      boolean this_present_consistency = true && this.isSetConsistency();
      boolean that_present_consistency = true && that.isSetConsistency();
      if (this_present_consistency || that_present_consistency) {
        if (!(this_present_consistency && that_present_consistency))
          return false;
        if (!this.consistency.equals(that.consistency))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_query = true && (isSetQuery());
      builder.append(present_query);
      if (present_query)
        builder.append(query);

      boolean present_compression = true && (isSetCompression());
      builder.append(present_compression);
      if (present_compression)
        builder.append(compression.getValue());

      boolean present_consistency = true && (isSetConsistency());
      builder.append(present_consistency);
      if (present_consistency)
        builder.append(consistency.getValue());

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_cql3_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetQuery()).compareTo(other.isSetQuery());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQuery()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.query, other.query);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetCompression()).compareTo(other.isSetCompression());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCompression()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.compression, other.compression);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency()).compareTo(other.isSetConsistency());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency, other.consistency);
        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("execute_cql3_query_args(");
      boolean first = true;

      sb.append("query:");
      if (this.query == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.query, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("compression:");
      if (this.compression == null) {
        sb.append("null");
      } else {
        sb.append(this.compression);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency:");
      if (this.consistency == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (query == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'query' was not present! Struct: " + toString());
      }
      if (compression == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'compression' was not present! Struct: " + toString());
      }
      if (consistency == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 execute_cql3_query_argsStandardSchemeFactory implements SchemeFactory {
      public execute_cql3_query_argsStandardScheme getScheme() {
        return new execute_cql3_query_argsStandardScheme();
      }
    }

    private static class execute_cql3_query_argsStandardScheme extends StandardScheme<execute_cql3_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_cql3_query_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: // QUERY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.query = iprot.readBinary();
                struct.setQueryIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COMPRESSION
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.compression = Compression.findByValue(iprot.readI32());
                struct.setCompressionIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSISTENCY
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistencyIsSet(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, execute_cql3_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.query != null) {
          oprot.writeFieldBegin(QUERY_FIELD_DESC);
          oprot.writeBinary(struct.query);
          oprot.writeFieldEnd();
        }
        if (struct.compression != null) {
          oprot.writeFieldBegin(COMPRESSION_FIELD_DESC);
          oprot.writeI32(struct.compression.getValue());
          oprot.writeFieldEnd();
        }
        if (struct.consistency != null) {
          oprot.writeFieldBegin(CONSISTENCY_FIELD_DESC);
          oprot.writeI32(struct.consistency.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_cql3_query_argsTupleSchemeFactory implements SchemeFactory {
      public execute_cql3_query_argsTupleScheme getScheme() {
        return new execute_cql3_query_argsTupleScheme();
      }
    }

    private static class execute_cql3_query_argsTupleScheme extends TupleScheme<execute_cql3_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_cql3_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.query);
        oprot.writeI32(struct.compression.getValue());
        oprot.writeI32(struct.consistency.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_cql3_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.query = iprot.readBinary();
        struct.setQueryIsSet(true);
        struct.compression = Compression.findByValue(iprot.readI32());
        struct.setCompressionIsSet(true);
        struct.consistency = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistencyIsSet(true);
      }
    }

  }

  public static class execute_cql3_query_result implements org.apache.thrift.TBase<execute_cql3_query_result, execute_cql3_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<execute_cql3_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_cql3_query_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_cql3_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_cql3_query_resultTupleSchemeFactory());
    }

    public CqlResult success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te"),
      SDE((short)4, "sde");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          case 4: // SDE
            return SDE;
          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, CqlResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(execute_cql3_query_result.class, metaDataMap);
    }

    public execute_cql3_query_result() {
    }

    public execute_cql3_query_result(
      CqlResult success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_cql3_query_result(execute_cql3_query_result other) {
      if (other.isSetSuccess()) {
        this.success = new CqlResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public execute_cql3_query_result deepCopy() {
      return new execute_cql3_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
      this.sde = null;
    }

    public CqlResult getSuccess() {
      return this.success;
    }

    public execute_cql3_query_result setSuccess(CqlResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public execute_cql3_query_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public UnavailableException getUe() {
      return this.ue;
    }

    public execute_cql3_query_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

    /** Returns true if field ue is set (has been assigned a value) and false otherwise */
    public boolean isSetUe() {
      return this.ue != null;
    }

    public void setUeIsSet(boolean value) {
      if (!value) {
        this.ue = null;
      }
    }

    public TimedOutException getTe() {
      return this.te;
    }

    public execute_cql3_query_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

    /** Returns true if field te is set (has been assigned a value) and false otherwise */
    public boolean isSetTe() {
      return this.te != null;
    }

    public void setTeIsSet(boolean value) {
      if (!value) {
        this.te = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public execute_cql3_query_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((CqlResult)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_cql3_query_result)
        return this.equals((execute_cql3_query_result)that);
      return false;
    }

    public boolean equals(execute_cql3_query_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_cql3_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("execute_cql3_query_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 execute_cql3_query_resultStandardSchemeFactory implements SchemeFactory {
      public execute_cql3_query_resultStandardScheme getScheme() {
        return new execute_cql3_query_resultStandardScheme();
      }
    }

    private static class execute_cql3_query_resultStandardScheme extends StandardScheme<execute_cql3_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_cql3_query_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 CqlResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, execute_cql3_query_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_cql3_query_resultTupleSchemeFactory implements SchemeFactory {
      public execute_cql3_query_resultTupleScheme getScheme() {
        return new execute_cql3_query_resultTupleScheme();
      }
    }

    private static class execute_cql3_query_resultTupleScheme extends TupleScheme<execute_cql3_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_cql3_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        if (struct.isSetSde()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_cql3_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new CqlResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
        if (incoming.get(4)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class prepare_cql_query_args implements org.apache.thrift.TBase<prepare_cql_query_args, prepare_cql_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<prepare_cql_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("prepare_cql_query_args");

    private static final org.apache.thrift.protocol.TField QUERY_FIELD_DESC = new org.apache.thrift.protocol.TField("query", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COMPRESSION_FIELD_DESC = new org.apache.thrift.protocol.TField("compression", 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 prepare_cql_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new prepare_cql_query_argsTupleSchemeFactory());
    }

    public ByteBuffer query; // required
    /**
     * 
     * @see Compression
     */
    public Compression compression; // 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 {
      QUERY((short)1, "query"),
      /**
       * 
       * @see Compression
       */
      COMPRESSION((short)2, "compression");

      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: // QUERY
            return QUERY;
          case 2: // COMPRESSION
            return COMPRESSION;
          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.QUERY, new org.apache.thrift.meta_data.FieldMetaData("query", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COMPRESSION, new org.apache.thrift.meta_data.FieldMetaData("compression", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Compression.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(prepare_cql_query_args.class, metaDataMap);
    }

    public prepare_cql_query_args() {
    }

    public prepare_cql_query_args(
      ByteBuffer query,
      Compression compression)
    {
      this();
      this.query = query;
      this.compression = compression;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public prepare_cql_query_args(prepare_cql_query_args other) {
      if (other.isSetQuery()) {
        this.query = org.apache.thrift.TBaseHelper.copyBinary(other.query);
;
      }
      if (other.isSetCompression()) {
        this.compression = other.compression;
      }
    }

    public prepare_cql_query_args deepCopy() {
      return new prepare_cql_query_args(this);
    }

    @Override
    public void clear() {
      this.query = null;
      this.compression = null;
    }

    public byte[] getQuery() {
      setQuery(org.apache.thrift.TBaseHelper.rightSize(query));
      return query == null ? null : query.array();
    }

    public ByteBuffer bufferForQuery() {
      return query;
    }

    public prepare_cql_query_args setQuery(byte[] query) {
      setQuery(query == null ? (ByteBuffer)null : ByteBuffer.wrap(query));
      return this;
    }

    public prepare_cql_query_args setQuery(ByteBuffer query) {
      this.query = query;
      return this;
    }

    public void unsetQuery() {
      this.query = null;
    }

    /** Returns true if field query is set (has been assigned a value) and false otherwise */
    public boolean isSetQuery() {
      return this.query != null;
    }

    public void setQueryIsSet(boolean value) {
      if (!value) {
        this.query = null;
      }
    }

    /**
     * 
     * @see Compression
     */
    public Compression getCompression() {
      return this.compression;
    }

    /**
     * 
     * @see Compression
     */
    public prepare_cql_query_args setCompression(Compression compression) {
      this.compression = compression;
      return this;
    }

    public void unsetCompression() {
      this.compression = null;
    }

    /** Returns true if field compression is set (has been assigned a value) and false otherwise */
    public boolean isSetCompression() {
      return this.compression != null;
    }

    public void setCompressionIsSet(boolean value) {
      if (!value) {
        this.compression = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case QUERY:
        if (value == null) {
          unsetQuery();
        } else {
          setQuery((ByteBuffer)value);
        }
        break;

      case COMPRESSION:
        if (value == null) {
          unsetCompression();
        } else {
          setCompression((Compression)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case QUERY:
        return getQuery();

      case COMPRESSION:
        return getCompression();

      }
      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 QUERY:
        return isSetQuery();
      case COMPRESSION:
        return isSetCompression();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof prepare_cql_query_args)
        return this.equals((prepare_cql_query_args)that);
      return false;
    }

    public boolean equals(prepare_cql_query_args that) {
      if (that == null)
        return false;

      boolean this_present_query = true && this.isSetQuery();
      boolean that_present_query = true && that.isSetQuery();
      if (this_present_query || that_present_query) {
        if (!(this_present_query && that_present_query))
          return false;
        if (!this.query.equals(that.query))
          return false;
      }

      boolean this_present_compression = true && this.isSetCompression();
      boolean that_present_compression = true && that.isSetCompression();
      if (this_present_compression || that_present_compression) {
        if (!(this_present_compression && that_present_compression))
          return false;
        if (!this.compression.equals(that.compression))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_query = true && (isSetQuery());
      builder.append(present_query);
      if (present_query)
        builder.append(query);

      boolean present_compression = true && (isSetCompression());
      builder.append(present_compression);
      if (present_compression)
        builder.append(compression.getValue());

      return builder.toHashCode();
    }

    @Override
    public int compareTo(prepare_cql_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetQuery()).compareTo(other.isSetQuery());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQuery()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.query, other.query);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetCompression()).compareTo(other.isSetCompression());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCompression()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.compression, other.compression);
        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("prepare_cql_query_args(");
      boolean first = true;

      sb.append("query:");
      if (this.query == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.query, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("compression:");
      if (this.compression == null) {
        sb.append("null");
      } else {
        sb.append(this.compression);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (query == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'query' was not present! Struct: " + toString());
      }
      if (compression == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'compression' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 prepare_cql_query_argsStandardSchemeFactory implements SchemeFactory {
      public prepare_cql_query_argsStandardScheme getScheme() {
        return new prepare_cql_query_argsStandardScheme();
      }
    }

    private static class prepare_cql_query_argsStandardScheme extends StandardScheme<prepare_cql_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, prepare_cql_query_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: // QUERY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.query = iprot.readBinary();
                struct.setQueryIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COMPRESSION
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.compression = Compression.findByValue(iprot.readI32());
                struct.setCompressionIsSet(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, prepare_cql_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.query != null) {
          oprot.writeFieldBegin(QUERY_FIELD_DESC);
          oprot.writeBinary(struct.query);
          oprot.writeFieldEnd();
        }
        if (struct.compression != null) {
          oprot.writeFieldBegin(COMPRESSION_FIELD_DESC);
          oprot.writeI32(struct.compression.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class prepare_cql_query_argsTupleSchemeFactory implements SchemeFactory {
      public prepare_cql_query_argsTupleScheme getScheme() {
        return new prepare_cql_query_argsTupleScheme();
      }
    }

    private static class prepare_cql_query_argsTupleScheme extends TupleScheme<prepare_cql_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, prepare_cql_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.query);
        oprot.writeI32(struct.compression.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, prepare_cql_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.query = iprot.readBinary();
        struct.setQueryIsSet(true);
        struct.compression = Compression.findByValue(iprot.readI32());
        struct.setCompressionIsSet(true);
      }
    }

  }

  public static class prepare_cql_query_result implements org.apache.thrift.TBase<prepare_cql_query_result, prepare_cql_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<prepare_cql_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("prepare_cql_query_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 prepare_cql_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new prepare_cql_query_resultTupleSchemeFactory());
    }

    public CqlPreparedResult success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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, CqlPreparedResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(prepare_cql_query_result.class, metaDataMap);
    }

    public prepare_cql_query_result() {
    }

    public prepare_cql_query_result(
      CqlPreparedResult success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public prepare_cql_query_result(prepare_cql_query_result other) {
      if (other.isSetSuccess()) {
        this.success = new CqlPreparedResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

    public prepare_cql_query_result deepCopy() {
      return new prepare_cql_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
    }

    public CqlPreparedResult getSuccess() {
      return this.success;
    }

    public prepare_cql_query_result setSuccess(CqlPreparedResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public prepare_cql_query_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((CqlPreparedResult)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof prepare_cql_query_result)
        return this.equals((prepare_cql_query_result)that);
      return false;
    }

    public boolean equals(prepare_cql_query_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(prepare_cql_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("prepare_cql_query_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 prepare_cql_query_resultStandardSchemeFactory implements SchemeFactory {
      public prepare_cql_query_resultStandardScheme getScheme() {
        return new prepare_cql_query_resultStandardScheme();
      }
    }

    private static class prepare_cql_query_resultStandardScheme extends StandardScheme<prepare_cql_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, prepare_cql_query_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 CqlPreparedResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, prepare_cql_query_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class prepare_cql_query_resultTupleSchemeFactory implements SchemeFactory {
      public prepare_cql_query_resultTupleScheme getScheme() {
        return new prepare_cql_query_resultTupleScheme();
      }
    }

    private static class prepare_cql_query_resultTupleScheme extends TupleScheme<prepare_cql_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, prepare_cql_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, prepare_cql_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new CqlPreparedResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

  public static class prepare_cql3_query_args implements org.apache.thrift.TBase<prepare_cql3_query_args, prepare_cql3_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<prepare_cql3_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("prepare_cql3_query_args");

    private static final org.apache.thrift.protocol.TField QUERY_FIELD_DESC = new org.apache.thrift.protocol.TField("query", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField COMPRESSION_FIELD_DESC = new org.apache.thrift.protocol.TField("compression", 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 prepare_cql3_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new prepare_cql3_query_argsTupleSchemeFactory());
    }

    public ByteBuffer query; // required
    /**
     * 
     * @see Compression
     */
    public Compression compression; // 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 {
      QUERY((short)1, "query"),
      /**
       * 
       * @see Compression
       */
      COMPRESSION((short)2, "compression");

      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: // QUERY
            return QUERY;
          case 2: // COMPRESSION
            return COMPRESSION;
          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.QUERY, new org.apache.thrift.meta_data.FieldMetaData("query", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
      tmpMap.put(_Fields.COMPRESSION, new org.apache.thrift.meta_data.FieldMetaData("compression", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Compression.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(prepare_cql3_query_args.class, metaDataMap);
    }

    public prepare_cql3_query_args() {
    }

    public prepare_cql3_query_args(
      ByteBuffer query,
      Compression compression)
    {
      this();
      this.query = query;
      this.compression = compression;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public prepare_cql3_query_args(prepare_cql3_query_args other) {
      if (other.isSetQuery()) {
        this.query = org.apache.thrift.TBaseHelper.copyBinary(other.query);
;
      }
      if (other.isSetCompression()) {
        this.compression = other.compression;
      }
    }

    public prepare_cql3_query_args deepCopy() {
      return new prepare_cql3_query_args(this);
    }

    @Override
    public void clear() {
      this.query = null;
      this.compression = null;
    }

    public byte[] getQuery() {
      setQuery(org.apache.thrift.TBaseHelper.rightSize(query));
      return query == null ? null : query.array();
    }

    public ByteBuffer bufferForQuery() {
      return query;
    }

    public prepare_cql3_query_args setQuery(byte[] query) {
      setQuery(query == null ? (ByteBuffer)null : ByteBuffer.wrap(query));
      return this;
    }

    public prepare_cql3_query_args setQuery(ByteBuffer query) {
      this.query = query;
      return this;
    }

    public void unsetQuery() {
      this.query = null;
    }

    /** Returns true if field query is set (has been assigned a value) and false otherwise */
    public boolean isSetQuery() {
      return this.query != null;
    }

    public void setQueryIsSet(boolean value) {
      if (!value) {
        this.query = null;
      }
    }

    /**
     * 
     * @see Compression
     */
    public Compression getCompression() {
      return this.compression;
    }

    /**
     * 
     * @see Compression
     */
    public prepare_cql3_query_args setCompression(Compression compression) {
      this.compression = compression;
      return this;
    }

    public void unsetCompression() {
      this.compression = null;
    }

    /** Returns true if field compression is set (has been assigned a value) and false otherwise */
    public boolean isSetCompression() {
      return this.compression != null;
    }

    public void setCompressionIsSet(boolean value) {
      if (!value) {
        this.compression = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case QUERY:
        if (value == null) {
          unsetQuery();
        } else {
          setQuery((ByteBuffer)value);
        }
        break;

      case COMPRESSION:
        if (value == null) {
          unsetCompression();
        } else {
          setCompression((Compression)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case QUERY:
        return getQuery();

      case COMPRESSION:
        return getCompression();

      }
      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 QUERY:
        return isSetQuery();
      case COMPRESSION:
        return isSetCompression();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof prepare_cql3_query_args)
        return this.equals((prepare_cql3_query_args)that);
      return false;
    }

    public boolean equals(prepare_cql3_query_args that) {
      if (that == null)
        return false;

      boolean this_present_query = true && this.isSetQuery();
      boolean that_present_query = true && that.isSetQuery();
      if (this_present_query || that_present_query) {
        if (!(this_present_query && that_present_query))
          return false;
        if (!this.query.equals(that.query))
          return false;
      }

      boolean this_present_compression = true && this.isSetCompression();
      boolean that_present_compression = true && that.isSetCompression();
      if (this_present_compression || that_present_compression) {
        if (!(this_present_compression && that_present_compression))
          return false;
        if (!this.compression.equals(that.compression))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_query = true && (isSetQuery());
      builder.append(present_query);
      if (present_query)
        builder.append(query);

      boolean present_compression = true && (isSetCompression());
      builder.append(present_compression);
      if (present_compression)
        builder.append(compression.getValue());

      return builder.toHashCode();
    }

    @Override
    public int compareTo(prepare_cql3_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetQuery()).compareTo(other.isSetQuery());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetQuery()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.query, other.query);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetCompression()).compareTo(other.isSetCompression());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCompression()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.compression, other.compression);
        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("prepare_cql3_query_args(");
      boolean first = true;

      sb.append("query:");
      if (this.query == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.query, sb);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("compression:");
      if (this.compression == null) {
        sb.append("null");
      } else {
        sb.append(this.compression);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (query == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'query' was not present! Struct: " + toString());
      }
      if (compression == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'compression' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 prepare_cql3_query_argsStandardSchemeFactory implements SchemeFactory {
      public prepare_cql3_query_argsStandardScheme getScheme() {
        return new prepare_cql3_query_argsStandardScheme();
      }
    }

    private static class prepare_cql3_query_argsStandardScheme extends StandardScheme<prepare_cql3_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, prepare_cql3_query_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: // QUERY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.query = iprot.readBinary();
                struct.setQueryIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // COMPRESSION
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.compression = Compression.findByValue(iprot.readI32());
                struct.setCompressionIsSet(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, prepare_cql3_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.query != null) {
          oprot.writeFieldBegin(QUERY_FIELD_DESC);
          oprot.writeBinary(struct.query);
          oprot.writeFieldEnd();
        }
        if (struct.compression != null) {
          oprot.writeFieldBegin(COMPRESSION_FIELD_DESC);
          oprot.writeI32(struct.compression.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class prepare_cql3_query_argsTupleSchemeFactory implements SchemeFactory {
      public prepare_cql3_query_argsTupleScheme getScheme() {
        return new prepare_cql3_query_argsTupleScheme();
      }
    }

    private static class prepare_cql3_query_argsTupleScheme extends TupleScheme<prepare_cql3_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, prepare_cql3_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeBinary(struct.query);
        oprot.writeI32(struct.compression.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, prepare_cql3_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.query = iprot.readBinary();
        struct.setQueryIsSet(true);
        struct.compression = Compression.findByValue(iprot.readI32());
        struct.setCompressionIsSet(true);
      }
    }

  }

  public static class prepare_cql3_query_result implements org.apache.thrift.TBase<prepare_cql3_query_result, prepare_cql3_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<prepare_cql3_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("prepare_cql3_query_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 prepare_cql3_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new prepare_cql3_query_resultTupleSchemeFactory());
    }

    public CqlPreparedResult success; // required
    public InvalidRequestException ire; // 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"),
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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, CqlPreparedResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(prepare_cql3_query_result.class, metaDataMap);
    }

    public prepare_cql3_query_result() {
    }

    public prepare_cql3_query_result(
      CqlPreparedResult success,
      InvalidRequestException ire)
    {
      this();
      this.success = success;
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public prepare_cql3_query_result(prepare_cql3_query_result other) {
      if (other.isSetSuccess()) {
        this.success = new CqlPreparedResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

    public prepare_cql3_query_result deepCopy() {
      return new prepare_cql3_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
    }

    public CqlPreparedResult getSuccess() {
      return this.success;
    }

    public prepare_cql3_query_result setSuccess(CqlPreparedResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public prepare_cql3_query_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((CqlPreparedResult)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof prepare_cql3_query_result)
        return this.equals((prepare_cql3_query_result)that);
      return false;
    }

    public boolean equals(prepare_cql3_query_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(prepare_cql3_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("prepare_cql3_query_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 prepare_cql3_query_resultStandardSchemeFactory implements SchemeFactory {
      public prepare_cql3_query_resultStandardScheme getScheme() {
        return new prepare_cql3_query_resultStandardScheme();
      }
    }

    private static class prepare_cql3_query_resultStandardScheme extends StandardScheme<prepare_cql3_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, prepare_cql3_query_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 CqlPreparedResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, prepare_cql3_query_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class prepare_cql3_query_resultTupleSchemeFactory implements SchemeFactory {
      public prepare_cql3_query_resultTupleScheme getScheme() {
        return new prepare_cql3_query_resultTupleScheme();
      }
    }

    private static class prepare_cql3_query_resultTupleScheme extends TupleScheme<prepare_cql3_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, prepare_cql3_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, prepare_cql3_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new CqlPreparedResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

  public static class execute_prepared_cql_query_args implements org.apache.thrift.TBase<execute_prepared_cql_query_args, execute_prepared_cql_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<execute_prepared_cql_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_prepared_cql_query_args");

    private static final org.apache.thrift.protocol.TField ITEM_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("itemId", org.apache.thrift.protocol.TType.I32, (short)1);
    private static final org.apache.thrift.protocol.TField VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("values", 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 execute_prepared_cql_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_prepared_cql_query_argsTupleSchemeFactory());
    }

    public int itemId; // required
    public List<ByteBuffer> values; // 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 {
      ITEM_ID((short)1, "itemId"),
      VALUES((short)2, "values");

      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: // ITEM_ID
            return ITEM_ID;
          case 2: // VALUES
            return VALUES;
          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 __ITEMID_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    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.ITEM_ID, new org.apache.thrift.meta_data.FieldMetaData("itemId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.VALUES, new org.apache.thrift.meta_data.FieldMetaData("values", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(execute_prepared_cql_query_args.class, metaDataMap);
    }

    public execute_prepared_cql_query_args() {
    }

    public execute_prepared_cql_query_args(
      int itemId,
      List<ByteBuffer> values)
    {
      this();
      this.itemId = itemId;
      setItemIdIsSet(true);
      this.values = values;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_prepared_cql_query_args(execute_prepared_cql_query_args other) {
      __isset_bitfield = other.__isset_bitfield;
      this.itemId = other.itemId;
      if (other.isSetValues()) {
        List<ByteBuffer> __this__values = new ArrayList<ByteBuffer>(other.values);
        this.values = __this__values;
      }
    }

    public execute_prepared_cql_query_args deepCopy() {
      return new execute_prepared_cql_query_args(this);
    }

    @Override
    public void clear() {
      setItemIdIsSet(false);
      this.itemId = 0;
      this.values = null;
    }

    public int getItemId() {
      return this.itemId;
    }

    public execute_prepared_cql_query_args setItemId(int itemId) {
      this.itemId = itemId;
      setItemIdIsSet(true);
      return this;
    }

    public void unsetItemId() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ITEMID_ISSET_ID);
    }

    /** Returns true if field itemId is set (has been assigned a value) and false otherwise */
    public boolean isSetItemId() {
      return EncodingUtils.testBit(__isset_bitfield, __ITEMID_ISSET_ID);
    }

    public void setItemIdIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ITEMID_ISSET_ID, value);
    }

    public int getValuesSize() {
      return (this.values == null) ? 0 : this.values.size();
    }

    public java.util.Iterator<ByteBuffer> getValuesIterator() {
      return (this.values == null) ? null : this.values.iterator();
    }

    public void addToValues(ByteBuffer elem) {
      if (this.values == null) {
        this.values = new ArrayList<ByteBuffer>();
      }
      this.values.add(elem);
    }

    public List<ByteBuffer> getValues() {
      return this.values;
    }

    public execute_prepared_cql_query_args setValues(List<ByteBuffer> values) {
      this.values = values;
      return this;
    }

    public void unsetValues() {
      this.values = null;
    }

    /** Returns true if field values is set (has been assigned a value) and false otherwise */
    public boolean isSetValues() {
      return this.values != null;
    }

    public void setValuesIsSet(boolean value) {
      if (!value) {
        this.values = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case ITEM_ID:
        if (value == null) {
          unsetItemId();
        } else {
          setItemId((Integer)value);
        }
        break;

      case VALUES:
        if (value == null) {
          unsetValues();
        } else {
          setValues((List<ByteBuffer>)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case ITEM_ID:
        return Integer.valueOf(getItemId());

      case VALUES:
        return getValues();

      }
      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 ITEM_ID:
        return isSetItemId();
      case VALUES:
        return isSetValues();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_prepared_cql_query_args)
        return this.equals((execute_prepared_cql_query_args)that);
      return false;
    }

    public boolean equals(execute_prepared_cql_query_args that) {
      if (that == null)
        return false;

      boolean this_present_itemId = true;
      boolean that_present_itemId = true;
      if (this_present_itemId || that_present_itemId) {
        if (!(this_present_itemId && that_present_itemId))
          return false;
        if (this.itemId != that.itemId)
          return false;
      }

      boolean this_present_values = true && this.isSetValues();
      boolean that_present_values = true && that.isSetValues();
      if (this_present_values || that_present_values) {
        if (!(this_present_values && that_present_values))
          return false;
        if (!this.values.equals(that.values))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_itemId = true;
      builder.append(present_itemId);
      if (present_itemId)
        builder.append(itemId);

      boolean present_values = true && (isSetValues());
      builder.append(present_values);
      if (present_values)
        builder.append(values);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_prepared_cql_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetItemId()).compareTo(other.isSetItemId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetItemId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.itemId, other.itemId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetValues()).compareTo(other.isSetValues());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValues()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.values, other.values);
        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("execute_prepared_cql_query_args(");
      boolean first = true;

      sb.append("itemId:");
      sb.append(this.itemId);
      first = false;
      if (!first) sb.append(", ");
      sb.append("values:");
      if (this.values == null) {
        sb.append("null");
      } else {
        sb.append(this.values);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // alas, we cannot check 'itemId' because it's a primitive and you chose the non-beans generator.
      if (values == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'values' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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_bitfield = 0;
        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 execute_prepared_cql_query_argsStandardSchemeFactory implements SchemeFactory {
      public execute_prepared_cql_query_argsStandardScheme getScheme() {
        return new execute_prepared_cql_query_argsStandardScheme();
      }
    }

    private static class execute_prepared_cql_query_argsStandardScheme extends StandardScheme<execute_prepared_cql_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_prepared_cql_query_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: // ITEM_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.itemId = iprot.readI32();
                struct.setItemIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // VALUES
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list448 = iprot.readListBegin();
                  struct.values = new ArrayList<ByteBuffer>(_list448.size);
                  for (int _i449 = 0; _i449 < _list448.size; ++_i449)
                  {
                    ByteBuffer _elem450;
                    _elem450 = iprot.readBinary();
                    struct.values.add(_elem450);
                  }
                  iprot.readListEnd();
                }
                struct.setValuesIsSet(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.isSetItemId()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'itemId' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, execute_prepared_cql_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(ITEM_ID_FIELD_DESC);
        oprot.writeI32(struct.itemId);
        oprot.writeFieldEnd();
        if (struct.values != null) {
          oprot.writeFieldBegin(VALUES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.values.size()));
            for (ByteBuffer _iter451 : struct.values)
            {
              oprot.writeBinary(_iter451);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_prepared_cql_query_argsTupleSchemeFactory implements SchemeFactory {
      public execute_prepared_cql_query_argsTupleScheme getScheme() {
        return new execute_prepared_cql_query_argsTupleScheme();
      }
    }

    private static class execute_prepared_cql_query_argsTupleScheme extends TupleScheme<execute_prepared_cql_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeI32(struct.itemId);
        {
          oprot.writeI32(struct.values.size());
          for (ByteBuffer _iter452 : struct.values)
          {
            oprot.writeBinary(_iter452);
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.itemId = iprot.readI32();
        struct.setItemIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list453 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.values = new ArrayList<ByteBuffer>(_list453.size);
          for (int _i454 = 0; _i454 < _list453.size; ++_i454)
          {
            ByteBuffer _elem455;
            _elem455 = iprot.readBinary();
            struct.values.add(_elem455);
          }
        }
        struct.setValuesIsSet(true);
      }
    }

  }

  public static class execute_prepared_cql_query_result implements org.apache.thrift.TBase<execute_prepared_cql_query_result, execute_prepared_cql_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<execute_prepared_cql_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_prepared_cql_query_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_prepared_cql_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_prepared_cql_query_resultTupleSchemeFactory());
    }

    public CqlResult success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te"),
      SDE((short)4, "sde");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          case 4: // SDE
            return SDE;
          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, CqlResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(execute_prepared_cql_query_result.class, metaDataMap);
    }

    public execute_prepared_cql_query_result() {
    }

    public execute_prepared_cql_query_result(
      CqlResult success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_prepared_cql_query_result(execute_prepared_cql_query_result other) {
      if (other.isSetSuccess()) {
        this.success = new CqlResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public execute_prepared_cql_query_result deepCopy() {
      return new execute_prepared_cql_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
      this.sde = null;
    }

    public CqlResult getSuccess() {
      return this.success;
    }

    public execute_prepared_cql_query_result setSuccess(CqlResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public execute_prepared_cql_query_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public UnavailableException getUe() {
      return this.ue;
    }

    public execute_prepared_cql_query_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

    /** Returns true if field ue is set (has been assigned a value) and false otherwise */
    public boolean isSetUe() {
      return this.ue != null;
    }

    public void setUeIsSet(boolean value) {
      if (!value) {
        this.ue = null;
      }
    }

    public TimedOutException getTe() {
      return this.te;
    }

    public execute_prepared_cql_query_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

    /** Returns true if field te is set (has been assigned a value) and false otherwise */
    public boolean isSetTe() {
      return this.te != null;
    }

    public void setTeIsSet(boolean value) {
      if (!value) {
        this.te = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public execute_prepared_cql_query_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((CqlResult)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_prepared_cql_query_result)
        return this.equals((execute_prepared_cql_query_result)that);
      return false;
    }

    public boolean equals(execute_prepared_cql_query_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_prepared_cql_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("execute_prepared_cql_query_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 execute_prepared_cql_query_resultStandardSchemeFactory implements SchemeFactory {
      public execute_prepared_cql_query_resultStandardScheme getScheme() {
        return new execute_prepared_cql_query_resultStandardScheme();
      }
    }

    private static class execute_prepared_cql_query_resultStandardScheme extends StandardScheme<execute_prepared_cql_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_prepared_cql_query_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 CqlResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, execute_prepared_cql_query_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_prepared_cql_query_resultTupleSchemeFactory implements SchemeFactory {
      public execute_prepared_cql_query_resultTupleScheme getScheme() {
        return new execute_prepared_cql_query_resultTupleScheme();
      }
    }

    private static class execute_prepared_cql_query_resultTupleScheme extends TupleScheme<execute_prepared_cql_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        if (struct.isSetSde()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new CqlResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
        if (incoming.get(4)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class execute_prepared_cql3_query_args implements org.apache.thrift.TBase<execute_prepared_cql3_query_args, execute_prepared_cql3_query_args._Fields>, java.io.Serializable, Cloneable, Comparable<execute_prepared_cql3_query_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_prepared_cql3_query_args");

    private static final org.apache.thrift.protocol.TField ITEM_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("itemId", org.apache.thrift.protocol.TType.I32, (short)1);
    private static final org.apache.thrift.protocol.TField VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("values", org.apache.thrift.protocol.TType.LIST, (short)2);
    private static final org.apache.thrift.protocol.TField CONSISTENCY_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_prepared_cql3_query_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_prepared_cql3_query_argsTupleSchemeFactory());
    }

    public int itemId; // required
    public List<ByteBuffer> values; // required
    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel consistency; // 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 {
      ITEM_ID((short)1, "itemId"),
      VALUES((short)2, "values"),
      /**
       * 
       * @see ConsistencyLevel
       */
      CONSISTENCY((short)3, "consistency");

      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: // ITEM_ID
            return ITEM_ID;
          case 2: // VALUES
            return VALUES;
          case 3: // CONSISTENCY
            return CONSISTENCY;
          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 __ITEMID_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    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.ITEM_ID, new org.apache.thrift.meta_data.FieldMetaData("itemId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.VALUES, new org.apache.thrift.meta_data.FieldMetaData("values", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
      tmpMap.put(_Fields.CONSISTENCY, new org.apache.thrift.meta_data.FieldMetaData("consistency", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(execute_prepared_cql3_query_args.class, metaDataMap);
    }

    public execute_prepared_cql3_query_args() {
    }

    public execute_prepared_cql3_query_args(
      int itemId,
      List<ByteBuffer> values,
      ConsistencyLevel consistency)
    {
      this();
      this.itemId = itemId;
      setItemIdIsSet(true);
      this.values = values;
      this.consistency = consistency;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_prepared_cql3_query_args(execute_prepared_cql3_query_args other) {
      __isset_bitfield = other.__isset_bitfield;
      this.itemId = other.itemId;
      if (other.isSetValues()) {
        List<ByteBuffer> __this__values = new ArrayList<ByteBuffer>(other.values);
        this.values = __this__values;
      }
      if (other.isSetConsistency()) {
        this.consistency = other.consistency;
      }
    }

    public execute_prepared_cql3_query_args deepCopy() {
      return new execute_prepared_cql3_query_args(this);
    }

    @Override
    public void clear() {
      setItemIdIsSet(false);
      this.itemId = 0;
      this.values = null;
      this.consistency = null;
    }

    public int getItemId() {
      return this.itemId;
    }

    public execute_prepared_cql3_query_args setItemId(int itemId) {
      this.itemId = itemId;
      setItemIdIsSet(true);
      return this;
    }

    public void unsetItemId() {
      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ITEMID_ISSET_ID);
    }

    /** Returns true if field itemId is set (has been assigned a value) and false otherwise */
    public boolean isSetItemId() {
      return EncodingUtils.testBit(__isset_bitfield, __ITEMID_ISSET_ID);
    }

    public void setItemIdIsSet(boolean value) {
      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ITEMID_ISSET_ID, value);
    }

    public int getValuesSize() {
      return (this.values == null) ? 0 : this.values.size();
    }

    public java.util.Iterator<ByteBuffer> getValuesIterator() {
      return (this.values == null) ? null : this.values.iterator();
    }

    public void addToValues(ByteBuffer elem) {
      if (this.values == null) {
        this.values = new ArrayList<ByteBuffer>();
      }
      this.values.add(elem);
    }

    public List<ByteBuffer> getValues() {
      return this.values;
    }

    public execute_prepared_cql3_query_args setValues(List<ByteBuffer> values) {
      this.values = values;
      return this;
    }

    public void unsetValues() {
      this.values = null;
    }

    /** Returns true if field values is set (has been assigned a value) and false otherwise */
    public boolean isSetValues() {
      return this.values != null;
    }

    public void setValuesIsSet(boolean value) {
      if (!value) {
        this.values = null;
      }
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public ConsistencyLevel getConsistency() {
      return this.consistency;
    }

    /**
     * 
     * @see ConsistencyLevel
     */
    public execute_prepared_cql3_query_args setConsistency(ConsistencyLevel consistency) {
      this.consistency = consistency;
      return this;
    }

    public void unsetConsistency() {
      this.consistency = null;
    }

    /** Returns true if field consistency is set (has been assigned a value) and false otherwise */
    public boolean isSetConsistency() {
      return this.consistency != null;
    }

    public void setConsistencyIsSet(boolean value) {
      if (!value) {
        this.consistency = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case ITEM_ID:
        if (value == null) {
          unsetItemId();
        } else {
          setItemId((Integer)value);
        }
        break;

      case VALUES:
        if (value == null) {
          unsetValues();
        } else {
          setValues((List<ByteBuffer>)value);
        }
        break;

      case CONSISTENCY:
        if (value == null) {
          unsetConsistency();
        } else {
          setConsistency((ConsistencyLevel)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case ITEM_ID:
        return Integer.valueOf(getItemId());

      case VALUES:
        return getValues();

      case CONSISTENCY:
        return getConsistency();

      }
      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 ITEM_ID:
        return isSetItemId();
      case VALUES:
        return isSetValues();
      case CONSISTENCY:
        return isSetConsistency();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_prepared_cql3_query_args)
        return this.equals((execute_prepared_cql3_query_args)that);
      return false;
    }

    public boolean equals(execute_prepared_cql3_query_args that) {
      if (that == null)
        return false;

      boolean this_present_itemId = true;
      boolean that_present_itemId = true;
      if (this_present_itemId || that_present_itemId) {
        if (!(this_present_itemId && that_present_itemId))
          return false;
        if (this.itemId != that.itemId)
          return false;
      }

      boolean this_present_values = true && this.isSetValues();
      boolean that_present_values = true && that.isSetValues();
      if (this_present_values || that_present_values) {
        if (!(this_present_values && that_present_values))
          return false;
        if (!this.values.equals(that.values))
          return false;
      }

      boolean this_present_consistency = true && this.isSetConsistency();
      boolean that_present_consistency = true && that.isSetConsistency();
      if (this_present_consistency || that_present_consistency) {
        if (!(this_present_consistency && that_present_consistency))
          return false;
        if (!this.consistency.equals(that.consistency))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_itemId = true;
      builder.append(present_itemId);
      if (present_itemId)
        builder.append(itemId);

      boolean present_values = true && (isSetValues());
      builder.append(present_values);
      if (present_values)
        builder.append(values);

      boolean present_consistency = true && (isSetConsistency());
      builder.append(present_consistency);
      if (present_consistency)
        builder.append(consistency.getValue());

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_prepared_cql3_query_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetItemId()).compareTo(other.isSetItemId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetItemId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.itemId, other.itemId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetValues()).compareTo(other.isSetValues());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetValues()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.values, other.values);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetConsistency()).compareTo(other.isSetConsistency());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetConsistency()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency, other.consistency);
        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("execute_prepared_cql3_query_args(");
      boolean first = true;

      sb.append("itemId:");
      sb.append(this.itemId);
      first = false;
      if (!first) sb.append(", ");
      sb.append("values:");
      if (this.values == null) {
        sb.append("null");
      } else {
        sb.append(this.values);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("consistency:");
      if (this.consistency == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // alas, we cannot check 'itemId' because it's a primitive and you chose the non-beans generator.
      if (values == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'values' was not present! Struct: " + toString());
      }
      if (consistency == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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_bitfield = 0;
        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 execute_prepared_cql3_query_argsStandardSchemeFactory implements SchemeFactory {
      public execute_prepared_cql3_query_argsStandardScheme getScheme() {
        return new execute_prepared_cql3_query_argsStandardScheme();
      }
    }

    private static class execute_prepared_cql3_query_argsStandardScheme extends StandardScheme<execute_prepared_cql3_query_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_prepared_cql3_query_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: // ITEM_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.itemId = iprot.readI32();
                struct.setItemIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // VALUES
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list456 = iprot.readListBegin();
                  struct.values = new ArrayList<ByteBuffer>(_list456.size);
                  for (int _i457 = 0; _i457 < _list456.size; ++_i457)
                  {
                    ByteBuffer _elem458;
                    _elem458 = iprot.readBinary();
                    struct.values.add(_elem458);
                  }
                  iprot.readListEnd();
                }
                struct.setValuesIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // CONSISTENCY
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.consistency = ConsistencyLevel.findByValue(iprot.readI32());
                struct.setConsistencyIsSet(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.isSetItemId()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'itemId' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, execute_prepared_cql3_query_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(ITEM_ID_FIELD_DESC);
        oprot.writeI32(struct.itemId);
        oprot.writeFieldEnd();
        if (struct.values != null) {
          oprot.writeFieldBegin(VALUES_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.values.size()));
            for (ByteBuffer _iter459 : struct.values)
            {
              oprot.writeBinary(_iter459);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.consistency != null) {
          oprot.writeFieldBegin(CONSISTENCY_FIELD_DESC);
          oprot.writeI32(struct.consistency.getValue());
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_prepared_cql3_query_argsTupleSchemeFactory implements SchemeFactory {
      public execute_prepared_cql3_query_argsTupleScheme getScheme() {
        return new execute_prepared_cql3_query_argsTupleScheme();
      }
    }

    private static class execute_prepared_cql3_query_argsTupleScheme extends TupleScheme<execute_prepared_cql3_query_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql3_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeI32(struct.itemId);
        {
          oprot.writeI32(struct.values.size());
          for (ByteBuffer _iter460 : struct.values)
          {
            oprot.writeBinary(_iter460);
          }
        }
        oprot.writeI32(struct.consistency.getValue());
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql3_query_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.itemId = iprot.readI32();
        struct.setItemIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list461 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.values = new ArrayList<ByteBuffer>(_list461.size);
          for (int _i462 = 0; _i462 < _list461.size; ++_i462)
          {
            ByteBuffer _elem463;
            _elem463 = iprot.readBinary();
            struct.values.add(_elem463);
          }
        }
        struct.setValuesIsSet(true);
        struct.consistency = ConsistencyLevel.findByValue(iprot.readI32());
        struct.setConsistencyIsSet(true);
      }
    }

  }

  public static class execute_prepared_cql3_query_result implements org.apache.thrift.TBase<execute_prepared_cql3_query_result, execute_prepared_cql3_query_result._Fields>, java.io.Serializable, Cloneable, Comparable<execute_prepared_cql3_query_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_prepared_cql3_query_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 IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);
    private static final org.apache.thrift.protocol.TField SDE_FIELD_DESC = new org.apache.thrift.protocol.TField("sde", org.apache.thrift.protocol.TType.STRUCT, (short)4);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new execute_prepared_cql3_query_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new execute_prepared_cql3_query_resultTupleSchemeFactory());
    }

    public CqlResult success; // required
    public InvalidRequestException ire; // required
    public UnavailableException ue; // required
    public TimedOutException te; // required
    public SchemaDisagreementException sde; // 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"),
      IRE((short)1, "ire"),
      UE((short)2, "ue"),
      TE((short)3, "te"),
      SDE((short)4, "sde");

      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: // IRE
            return IRE;
          case 2: // UE
            return UE;
          case 3: // TE
            return TE;
          case 4: // SDE
            return SDE;
          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, CqlResult.class)));
      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
      tmpMap.put(_Fields.SDE, new org.apache.thrift.meta_data.FieldMetaData("sde", 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(execute_prepared_cql3_query_result.class, metaDataMap);
    }

    public execute_prepared_cql3_query_result() {
    }

    public execute_prepared_cql3_query_result(
      CqlResult success,
      InvalidRequestException ire,
      UnavailableException ue,
      TimedOutException te,
      SchemaDisagreementException sde)
    {
      this();
      this.success = success;
      this.ire = ire;
      this.ue = ue;
      this.te = te;
      this.sde = sde;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public execute_prepared_cql3_query_result(execute_prepared_cql3_query_result other) {
      if (other.isSetSuccess()) {
        this.success = new CqlResult(other.success);
      }
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
      if (other.isSetUe()) {
        this.ue = new UnavailableException(other.ue);
      }
      if (other.isSetTe()) {
        this.te = new TimedOutException(other.te);
      }
      if (other.isSetSde()) {
        this.sde = new SchemaDisagreementException(other.sde);
      }
    }

    public execute_prepared_cql3_query_result deepCopy() {
      return new execute_prepared_cql3_query_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.ire = null;
      this.ue = null;
      this.te = null;
      this.sde = null;
    }

    public CqlResult getSuccess() {
      return this.success;
    }

    public execute_prepared_cql3_query_result setSuccess(CqlResult 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 InvalidRequestException getIre() {
      return this.ire;
    }

    public execute_prepared_cql3_query_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public UnavailableException getUe() {
      return this.ue;
    }

    public execute_prepared_cql3_query_result setUe(UnavailableException ue) {
      this.ue = ue;
      return this;
    }

    public void unsetUe() {
      this.ue = null;
    }

    /** Returns true if field ue is set (has been assigned a value) and false otherwise */
    public boolean isSetUe() {
      return this.ue != null;
    }

    public void setUeIsSet(boolean value) {
      if (!value) {
        this.ue = null;
      }
    }

    public TimedOutException getTe() {
      return this.te;
    }

    public execute_prepared_cql3_query_result setTe(TimedOutException te) {
      this.te = te;
      return this;
    }

    public void unsetTe() {
      this.te = null;
    }

    /** Returns true if field te is set (has been assigned a value) and false otherwise */
    public boolean isSetTe() {
      return this.te != null;
    }

    public void setTeIsSet(boolean value) {
      if (!value) {
        this.te = null;
      }
    }

    public SchemaDisagreementException getSde() {
      return this.sde;
    }

    public execute_prepared_cql3_query_result setSde(SchemaDisagreementException sde) {
      this.sde = sde;
      return this;
    }

    public void unsetSde() {
      this.sde = null;
    }

    /** Returns true if field sde is set (has been assigned a value) and false otherwise */
    public boolean isSetSde() {
      return this.sde != null;
    }

    public void setSdeIsSet(boolean value) {
      if (!value) {
        this.sde = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((CqlResult)value);
        }
        break;

      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      case UE:
        if (value == null) {
          unsetUe();
        } else {
          setUe((UnavailableException)value);
        }
        break;

      case TE:
        if (value == null) {
          unsetTe();
        } else {
          setTe((TimedOutException)value);
        }
        break;

      case SDE:
        if (value == null) {
          unsetSde();
        } else {
          setSde((SchemaDisagreementException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case IRE:
        return getIre();

      case UE:
        return getUe();

      case TE:
        return getTe();

      case SDE:
        return getSde();

      }
      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 IRE:
        return isSetIre();
      case UE:
        return isSetUe();
      case TE:
        return isSetTe();
      case SDE:
        return isSetSde();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof execute_prepared_cql3_query_result)
        return this.equals((execute_prepared_cql3_query_result)that);
      return false;
    }

    public boolean equals(execute_prepared_cql3_query_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_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      boolean this_present_ue = true && this.isSetUe();
      boolean that_present_ue = true && that.isSetUe();
      if (this_present_ue || that_present_ue) {
        if (!(this_present_ue && that_present_ue))
          return false;
        if (!this.ue.equals(that.ue))
          return false;
      }

      boolean this_present_te = true && this.isSetTe();
      boolean that_present_te = true && that.isSetTe();
      if (this_present_te || that_present_te) {
        if (!(this_present_te && that_present_te))
          return false;
        if (!this.te.equals(that.te))
          return false;
      }

      boolean this_present_sde = true && this.isSetSde();
      boolean that_present_sde = true && that.isSetSde();
      if (this_present_sde || that_present_sde) {
        if (!(this_present_sde && that_present_sde))
          return false;
        if (!this.sde.equals(that.sde))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_success = true && (isSetSuccess());
      builder.append(present_success);
      if (present_success)
        builder.append(success);

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      boolean present_ue = true && (isSetUe());
      builder.append(present_ue);
      if (present_ue)
        builder.append(ue);

      boolean present_te = true && (isSetTe());
      builder.append(present_te);
      if (present_te)
        builder.append(te);

      boolean present_sde = true && (isSetSde());
      builder.append(present_sde);
      if (present_sde)
        builder.append(sde);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(execute_prepared_cql3_query_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetUe()).compareTo(other.isSetUe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, other.ue);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetTe()).compareTo(other.isSetTe());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetTe()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, other.te);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = Boolean.valueOf(isSetSde()).compareTo(other.isSetSde());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSde()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sde, other.sde);
        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("execute_prepared_cql3_query_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("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ue:");
      if (this.ue == null) {
        sb.append("null");
      } else {
        sb.append(this.ue);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("te:");
      if (this.te == null) {
        sb.append("null");
      } else {
        sb.append(this.te);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sde:");
      if (this.sde == null) {
        sb.append("null");
      } else {
        sb.append(this.sde);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 execute_prepared_cql3_query_resultStandardSchemeFactory implements SchemeFactory {
      public execute_prepared_cql3_query_resultStandardScheme getScheme() {
        return new execute_prepared_cql3_query_resultStandardScheme();
      }
    }

    private static class execute_prepared_cql3_query_resultStandardScheme extends StandardScheme<execute_prepared_cql3_query_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_prepared_cql3_query_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 CqlResult();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // UE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ue = new UnavailableException();
                struct.ue.read(iprot);
                struct.setUeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // TE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.te = new TimedOutException();
                struct.te.read(iprot);
                struct.setTeIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // SDE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sde = new SchemaDisagreementException();
                struct.sde.read(iprot);
                struct.setSdeIsSet(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, execute_prepared_cql3_query_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.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.ue != null) {
          oprot.writeFieldBegin(UE_FIELD_DESC);
          struct.ue.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.te != null) {
          oprot.writeFieldBegin(TE_FIELD_DESC);
          struct.te.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sde != null) {
          oprot.writeFieldBegin(SDE_FIELD_DESC);
          struct.sde.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class execute_prepared_cql3_query_resultTupleSchemeFactory implements SchemeFactory {
      public execute_prepared_cql3_query_resultTupleScheme getScheme() {
        return new execute_prepared_cql3_query_resultTupleScheme();
      }
    }

    private static class execute_prepared_cql3_query_resultTupleScheme extends TupleScheme<execute_prepared_cql3_query_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql3_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetIre()) {
          optionals.set(1);
        }
        if (struct.isSetUe()) {
          optionals.set(2);
        }
        if (struct.isSetTe()) {
          optionals.set(3);
        }
        if (struct.isSetSde()) {
          optionals.set(4);
        }
        oprot.writeBitSet(optionals, 5);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
        if (struct.isSetUe()) {
          struct.ue.write(oprot);
        }
        if (struct.isSetTe()) {
          struct.te.write(oprot);
        }
        if (struct.isSetSde()) {
          struct.sde.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, execute_prepared_cql3_query_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(5);
        if (incoming.get(0)) {
          struct.success = new CqlResult();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.ue = new UnavailableException();
          struct.ue.read(iprot);
          struct.setUeIsSet(true);
        }
        if (incoming.get(3)) {
          struct.te = new TimedOutException();
          struct.te.read(iprot);
          struct.setTeIsSet(true);
        }
        if (incoming.get(4)) {
          struct.sde = new SchemaDisagreementException();
          struct.sde.read(iprot);
          struct.setSdeIsSet(true);
        }
      }
    }

  }

  public static class set_cql_version_args implements org.apache.thrift.TBase<set_cql_version_args, set_cql_version_args._Fields>, java.io.Serializable, Cloneable, Comparable<set_cql_version_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("set_cql_version_args");

    private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRING, (short)1);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
      schemes.put(StandardScheme.class, new set_cql_version_argsStandardSchemeFactory());
      schemes.put(TupleScheme.class, new set_cql_version_argsTupleSchemeFactory());
    }

    public String version; // 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 {
      VERSION((short)1, "version");

      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: // VERSION
            return VERSION;
          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.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(set_cql_version_args.class, metaDataMap);
    }

    public set_cql_version_args() {
    }

    public set_cql_version_args(
      String version)
    {
      this();
      this.version = version;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public set_cql_version_args(set_cql_version_args other) {
      if (other.isSetVersion()) {
        this.version = other.version;
      }
    }

    public set_cql_version_args deepCopy() {
      return new set_cql_version_args(this);
    }

    @Override
    public void clear() {
      this.version = null;
    }

    public String getVersion() {
      return this.version;
    }

    public set_cql_version_args setVersion(String version) {
      this.version = version;
      return this;
    }

    public void unsetVersion() {
      this.version = null;
    }

    /** Returns true if field version is set (has been assigned a value) and false otherwise */
    public boolean isSetVersion() {
      return this.version != null;
    }

    public void setVersionIsSet(boolean value) {
      if (!value) {
        this.version = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case VERSION:
        if (value == null) {
          unsetVersion();
        } else {
          setVersion((String)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case VERSION:
        return getVersion();

      }
      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 VERSION:
        return isSetVersion();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof set_cql_version_args)
        return this.equals((set_cql_version_args)that);
      return false;
    }

    public boolean equals(set_cql_version_args that) {
      if (that == null)
        return false;

      boolean this_present_version = true && this.isSetVersion();
      boolean that_present_version = true && that.isSetVersion();
      if (this_present_version || that_present_version) {
        if (!(this_present_version && that_present_version))
          return false;
        if (!this.version.equals(that.version))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_version = true && (isSetVersion());
      builder.append(present_version);
      if (present_version)
        builder.append(version);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(set_cql_version_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetVersion()).compareTo(other.isSetVersion());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetVersion()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, other.version);
        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("set_cql_version_args(");
      boolean first = true;

      sb.append("version:");
      if (this.version == null) {
        sb.append("null");
      } else {
        sb.append(this.version);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (version == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'version' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    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 set_cql_version_argsStandardSchemeFactory implements SchemeFactory {
      public set_cql_version_argsStandardScheme getScheme() {
        return new set_cql_version_argsStandardScheme();
      }
    }

    private static class set_cql_version_argsStandardScheme extends StandardScheme<set_cql_version_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, set_cql_version_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: // VERSION
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.version = iprot.readString();
                struct.setVersionIsSet(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, set_cql_version_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.version != null) {
          oprot.writeFieldBegin(VERSION_FIELD_DESC);
          oprot.writeString(struct.version);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class set_cql_version_argsTupleSchemeFactory implements SchemeFactory {
      public set_cql_version_argsTupleScheme getScheme() {
        return new set_cql_version_argsTupleScheme();
      }
    }

    private static class set_cql_version_argsTupleScheme extends TupleScheme<set_cql_version_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, set_cql_version_args struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        oprot.writeString(struct.version);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, set_cql_version_args struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        struct.version = iprot.readString();
        struct.setVersionIsSet(true);
      }
    }

  }

  public static class set_cql_version_result implements org.apache.thrift.TBase<set_cql_version_result, set_cql_version_result._Fields>, java.io.Serializable, Cloneable, Comparable<set_cql_version_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("set_cql_version_result");

    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", 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 set_cql_version_resultStandardSchemeFactory());
      schemes.put(TupleScheme.class, new set_cql_version_resultTupleSchemeFactory());
    }

    public InvalidRequestException ire; // 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 {
      IRE((short)1, "ire");

      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: // IRE
            return IRE;
          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.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", 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(set_cql_version_result.class, metaDataMap);
    }

    public set_cql_version_result() {
    }

    public set_cql_version_result(
      InvalidRequestException ire)
    {
      this();
      this.ire = ire;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public set_cql_version_result(set_cql_version_result other) {
      if (other.isSetIre()) {
        this.ire = new InvalidRequestException(other.ire);
      }
    }

    public set_cql_version_result deepCopy() {
      return new set_cql_version_result(this);
    }

    @Override
    public void clear() {
      this.ire = null;
    }

    public InvalidRequestException getIre() {
      return this.ire;
    }

    public set_cql_version_result setIre(InvalidRequestException ire) {
      this.ire = ire;
      return this;
    }

    public void unsetIre() {
      this.ire = null;
    }

    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
    public boolean isSetIre() {
      return this.ire != null;
    }

    public void setIreIsSet(boolean value) {
      if (!value) {
        this.ire = null;
      }
    }

    public void setFieldValue(_Fields field, Object value) {
      switch (field) {
      case IRE:
        if (value == null) {
          unsetIre();
        } else {
          setIre((InvalidRequestException)value);
        }
        break;

      }
    }

    public Object getFieldValue(_Fields field) {
      switch (field) {
      case IRE:
        return getIre();

      }
      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 IRE:
        return isSetIre();
      }
      throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
      if (that == null)
        return false;
      if (that instanceof set_cql_version_result)
        return this.equals((set_cql_version_result)that);
      return false;
    }

    public boolean equals(set_cql_version_result that) {
      if (that == null)
        return false;

      boolean this_present_ire = true && this.isSetIre();
      boolean that_present_ire = true && that.isSetIre();
      if (this_present_ire || that_present_ire) {
        if (!(this_present_ire && that_present_ire))
          return false;
        if (!this.ire.equals(that.ire))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      HashCodeBuilder builder = new HashCodeBuilder();

      boolean present_ire = true && (isSetIre());
      builder.append(present_ire);
      if (present_ire)
        builder.append(ire);

      return builder.toHashCode();
    }

    @Override
    public int compareTo(set_cql_version_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = Boolean.valueOf(isSetIre()).compareTo(other.isSetIre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetIre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, other.ire);
        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("set_cql_version_result(");
      boolean first = true;

      sb.append("ire:");
      if (this.ire == null) {
        sb.append("null");
      } else {
        sb.append(this.ire);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    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 set_cql_version_resultStandardSchemeFactory implements SchemeFactory {
      public set_cql_version_resultStandardScheme getScheme() {
        return new set_cql_version_resultStandardScheme();
      }
    }

    private static class set_cql_version_resultStandardScheme extends StandardScheme<set_cql_version_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, set_cql_version_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: // IRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.ire = new InvalidRequestException();
                struct.ire.read(iprot);
                struct.setIreIsSet(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, set_cql_version_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.ire != null) {
          oprot.writeFieldBegin(IRE_FIELD_DESC);
          struct.ire.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class set_cql_version_resultTupleSchemeFactory implements SchemeFactory {
      public set_cql_version_resultTupleScheme getScheme() {
        return new set_cql_version_resultTupleScheme();
      }
    }

    private static class set_cql_version_resultTupleScheme extends TupleScheme<set_cql_version_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, set_cql_version_result struct) throws org.apache.thrift.TException {
        TTupleProtocol oprot = (TTupleProtocol) prot;
        BitSet optionals = new BitSet();
        if (struct.isSetIre()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetIre()) {
          struct.ire.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, set_cql_version_result struct) throws org.apache.thrift.TException {
        TTupleProtocol iprot = (TTupleProtocol) prot;
        BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.ire = new InvalidRequestException();
          struct.ire.read(iprot);
          struct.setIreIsSet(true);
        }
      }
    }

  }

}
