#
# Autogenerated by Thrift Compiler (0.8.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

from thrift.Thrift import TType, TMessageType, TException
from .ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol, TProtocol
try:
  from thrift.protocol import fastbinary
except:
  fastbinary = None


class Iface:
  def login(self, auth_request):
    """
    Parameters:
     - auth_request
    """
    pass

  def set_keyspace(self, keyspace):
    """
    Parameters:
     - keyspace
    """
    pass

  def get(self, key, column_path, consistency_level):
    """
    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.)

    Parameters:
     - key
     - column_path
     - consistency_level
    """
    pass

  def get_slice(self, key, column_parent, predicate, consistency_level):
    """
    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.

    Parameters:
     - key
     - column_parent
     - predicate
     - consistency_level
    """
    pass

  def get_count(self, key, column_parent, predicate, consistency_level):
    """
    returns the number of columns matching <code>predicate</code> for a particular <code>key</code>,
    <code>ColumnFamily</code> and optionally <code>SuperColumn</code>.

    Parameters:
     - key
     - column_parent
     - predicate
     - consistency_level
    """
    pass

  def multiget_slice(self, keys, column_parent, predicate, consistency_level):
    """
    Performs a get_slice for column_parent and predicate for the given keys in parallel.

    Parameters:
     - keys
     - column_parent
     - predicate
     - consistency_level
    """
    pass

  def multiget_count(self, keys, column_parent, predicate, consistency_level):
    """
    Perform a get_count in parallel on the given list<binary> keys. The return value maps keys to the count found.

    Parameters:
     - keys
     - column_parent
     - predicate
     - consistency_level
    """
    pass

  def get_range_slices(self, column_parent, predicate, range, consistency_level):
    """
    returns a subset of columns for a contiguous range of keys.

    Parameters:
     - column_parent
     - predicate
     - range
     - consistency_level
    """
    pass

  def get_paged_slice(self, column_family, range, start_column, consistency_level):
    """
    returns a range of columns, wrapping to the next rows if necessary to collect max_results.

    Parameters:
     - column_family
     - range
     - start_column
     - consistency_level
    """
    pass

  def get_indexed_slices(self, column_parent, index_clause, column_predicate, consistency_level):
    """
    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

    Parameters:
     - column_parent
     - index_clause
     - column_predicate
     - consistency_level
    """
    pass

  def insert(self, key, column_parent, column, consistency_level):
    """
    Insert a Column at the given column_parent.column_family and optional column_parent.super_column.

    Parameters:
     - key
     - column_parent
     - column
     - consistency_level
    """
    pass

  def add(self, key, column_parent, column, consistency_level):
    """
    Increment or decrement a counter.

    Parameters:
     - key
     - column_parent
     - column
     - consistency_level
    """
    pass

  def remove(self, key, column_path, timestamp, consistency_level):
    """
    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.

    Parameters:
     - key
     - column_path
     - timestamp
     - consistency_level
    """
    pass

  def remove_counter(self, key, path, consistency_level):
    """
    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.

    Parameters:
     - key
     - path
     - consistency_level
    """
    pass

  def batch_mutate(self, mutation_map, consistency_level):
    """
      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.
    *

    Parameters:
     - mutation_map
     - consistency_level
    """
    pass

  def truncate(self, cfname):
    """
    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.

    Parameters:
     - cfname
    """
    pass

  def describe_schema_versions(self, ):
    """
    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.
    """
    pass

  def describe_keyspaces(self, ):
    """
    list the defined keyspaces in this cluster
    """
    pass

  def describe_cluster_name(self, ):
    """
    get the cluster name
    """
    pass

  def describe_version(self, ):
    """
    get the thrift api version
    """
    pass

  def describe_ring(self, keyspace):
    """
    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.

    Parameters:
     - keyspace
    """
    pass

  def describe_partitioner(self, ):
    """
    returns the partitioner used by this cluster
    """
    pass

  def describe_snitch(self, ):
    """
    returns the snitch used by this cluster
    """
    pass

  def describe_keyspace(self, keyspace):
    """
    describe specified keyspace

    Parameters:
     - keyspace
    """
    pass

  def describe_splits(self, cfName, start_token, end_token, keys_per_split):
    """
    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.

    Parameters:
     - cfName
     - start_token
     - end_token
     - keys_per_split
    """
    pass

  def system_add_column_family(self, cf_def):
    """
    adds a column family. returns the new schema id.

    Parameters:
     - cf_def
    """
    pass

  def system_drop_column_family(self, column_family):
    """
    drops a column family. returns the new schema id.

    Parameters:
     - column_family
    """
    pass

  def system_add_keyspace(self, ks_def):
    """
    adds a keyspace and any column families that are part of it. returns the new schema id.

    Parameters:
     - ks_def
    """
    pass

  def system_drop_keyspace(self, keyspace):
    """
    drops a keyspace and any column families that are part of it. returns the new schema id.

    Parameters:
     - keyspace
    """
    pass

  def system_update_keyspace(self, ks_def):
    """
    updates properties of a keyspace. returns the new schema id.

    Parameters:
     - ks_def
    """
    pass

  def system_update_column_family(self, cf_def):
    """
    updates properties of a column family. returns the new schema id.

    Parameters:
     - cf_def
    """
    pass

  def execute_cql_query(self, query, compression):
    """
    Executes a CQL (Cassandra Query Language) statement and returns a
    CqlResult containing the results.

    Parameters:
     - query
     - compression
    """
    pass

  def prepare_cql_query(self, query, compression):
    """
    Prepare a CQL (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

    Parameters:
     - query
     - compression
    """
    pass

  def execute_prepared_cql_query(self, itemId, values):
    """
    Executes a prepared CQL (Cassandra Query Language) statement by passing an id token and  a list of variables
    to bind and returns a CqlResult containing the results.

    Parameters:
     - itemId
     - values
    """
    pass

  def set_cql_version(self, version):
    """
    Parameters:
     - version
    """
    pass


class Client(Iface):
  def __init__(self, iprot, oprot=None):
    self._iprot = self._oprot = iprot
    if oprot is not None:
      self._oprot = oprot
    self._seqid = 0

  def login(self, auth_request):
    """
    Parameters:
     - auth_request
    """
    self.send_login(auth_request)
    self.recv_login()

  def send_login(self, auth_request):
    self._oprot.writeMessageBegin('login', TMessageType.CALL, self._seqid)
    args = login_args()
    args.auth_request = auth_request
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_login(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = login_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.authnx is not None:
      raise result.authnx
    if result.authzx is not None:
      raise result.authzx
    return

  def set_keyspace(self, keyspace):
    """
    Parameters:
     - keyspace
    """
    self.send_set_keyspace(keyspace)
    self.recv_set_keyspace()

  def send_set_keyspace(self, keyspace):
    self._oprot.writeMessageBegin('set_keyspace', TMessageType.CALL, self._seqid)
    args = set_keyspace_args()
    args.keyspace = keyspace
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_set_keyspace(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = set_keyspace_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    return

  def get(self, key, column_path, consistency_level):
    """
    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.)

    Parameters:
     - key
     - column_path
     - consistency_level
    """
    self.send_get(key, column_path, consistency_level)
    return self.recv_get()

  def send_get(self, key, column_path, consistency_level):
    self._oprot.writeMessageBegin('get', TMessageType.CALL, self._seqid)
    args = get_args()
    args.key = key
    args.column_path = column_path
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_get(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = get_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.nfe is not None:
      raise result.nfe
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "get failed: unknown result");

  def get_slice(self, key, column_parent, predicate, consistency_level):
    """
    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.

    Parameters:
     - key
     - column_parent
     - predicate
     - consistency_level
    """
    self.send_get_slice(key, column_parent, predicate, consistency_level)
    return self.recv_get_slice()

  def send_get_slice(self, key, column_parent, predicate, consistency_level):
    self._oprot.writeMessageBegin('get_slice', TMessageType.CALL, self._seqid)
    args = get_slice_args()
    args.key = key
    args.column_parent = column_parent
    args.predicate = predicate
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_get_slice(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = get_slice_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "get_slice failed: unknown result");

  def get_count(self, key, column_parent, predicate, consistency_level):
    """
    returns the number of columns matching <code>predicate</code> for a particular <code>key</code>,
    <code>ColumnFamily</code> and optionally <code>SuperColumn</code>.

    Parameters:
     - key
     - column_parent
     - predicate
     - consistency_level
    """
    self.send_get_count(key, column_parent, predicate, consistency_level)
    return self.recv_get_count()

  def send_get_count(self, key, column_parent, predicate, consistency_level):
    self._oprot.writeMessageBegin('get_count', TMessageType.CALL, self._seqid)
    args = get_count_args()
    args.key = key
    args.column_parent = column_parent
    args.predicate = predicate
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_get_count(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = get_count_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "get_count failed: unknown result");

  def multiget_slice(self, keys, column_parent, predicate, consistency_level):
    """
    Performs a get_slice for column_parent and predicate for the given keys in parallel.

    Parameters:
     - keys
     - column_parent
     - predicate
     - consistency_level
    """
    self.send_multiget_slice(keys, column_parent, predicate, consistency_level)
    return self.recv_multiget_slice()

  def send_multiget_slice(self, keys, column_parent, predicate, consistency_level):
    self._oprot.writeMessageBegin('multiget_slice', TMessageType.CALL, self._seqid)
    args = multiget_slice_args()
    args.keys = keys
    args.column_parent = column_parent
    args.predicate = predicate
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_multiget_slice(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = multiget_slice_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "multiget_slice failed: unknown result");

  def multiget_count(self, keys, column_parent, predicate, consistency_level):
    """
    Perform a get_count in parallel on the given list<binary> keys. The return value maps keys to the count found.

    Parameters:
     - keys
     - column_parent
     - predicate
     - consistency_level
    """
    self.send_multiget_count(keys, column_parent, predicate, consistency_level)
    return self.recv_multiget_count()

  def send_multiget_count(self, keys, column_parent, predicate, consistency_level):
    self._oprot.writeMessageBegin('multiget_count', TMessageType.CALL, self._seqid)
    args = multiget_count_args()
    args.keys = keys
    args.column_parent = column_parent
    args.predicate = predicate
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_multiget_count(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = multiget_count_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "multiget_count failed: unknown result");

  def get_range_slices(self, column_parent, predicate, range, consistency_level):
    """
    returns a subset of columns for a contiguous range of keys.

    Parameters:
     - column_parent
     - predicate
     - range
     - consistency_level
    """
    self.send_get_range_slices(column_parent, predicate, range, consistency_level)
    return self.recv_get_range_slices()

  def send_get_range_slices(self, column_parent, predicate, range, consistency_level):
    self._oprot.writeMessageBegin('get_range_slices', TMessageType.CALL, self._seqid)
    args = get_range_slices_args()
    args.column_parent = column_parent
    args.predicate = predicate
    args.range = range
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_get_range_slices(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = get_range_slices_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "get_range_slices failed: unknown result");

  def get_paged_slice(self, column_family, range, start_column, consistency_level):
    """
    returns a range of columns, wrapping to the next rows if necessary to collect max_results.

    Parameters:
     - column_family
     - range
     - start_column
     - consistency_level
    """
    self.send_get_paged_slice(column_family, range, start_column, consistency_level)
    return self.recv_get_paged_slice()

  def send_get_paged_slice(self, column_family, range, start_column, consistency_level):
    self._oprot.writeMessageBegin('get_paged_slice', TMessageType.CALL, self._seqid)
    args = get_paged_slice_args()
    args.column_family = column_family
    args.range = range
    args.start_column = start_column
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_get_paged_slice(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = get_paged_slice_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "get_paged_slice failed: unknown result");

  def get_indexed_slices(self, column_parent, index_clause, column_predicate, consistency_level):
    """
    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

    Parameters:
     - column_parent
     - index_clause
     - column_predicate
     - consistency_level
    """
    self.send_get_indexed_slices(column_parent, index_clause, column_predicate, consistency_level)
    return self.recv_get_indexed_slices()

  def send_get_indexed_slices(self, column_parent, index_clause, column_predicate, consistency_level):
    self._oprot.writeMessageBegin('get_indexed_slices', TMessageType.CALL, self._seqid)
    args = get_indexed_slices_args()
    args.column_parent = column_parent
    args.index_clause = index_clause
    args.column_predicate = column_predicate
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_get_indexed_slices(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = get_indexed_slices_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    raise TApplicationException(TApplicationException.MISSING_RESULT, "get_indexed_slices failed: unknown result");

  def insert(self, key, column_parent, column, consistency_level):
    """
    Insert a Column at the given column_parent.column_family and optional column_parent.super_column.

    Parameters:
     - key
     - column_parent
     - column
     - consistency_level
    """
    self.send_insert(key, column_parent, column, consistency_level)
    self.recv_insert()

  def send_insert(self, key, column_parent, column, consistency_level):
    self._oprot.writeMessageBegin('insert', TMessageType.CALL, self._seqid)
    args = insert_args()
    args.key = key
    args.column_parent = column_parent
    args.column = column
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_insert(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = insert_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    return

  def add(self, key, column_parent, column, consistency_level):
    """
    Increment or decrement a counter.

    Parameters:
     - key
     - column_parent
     - column
     - consistency_level
    """
    self.send_add(key, column_parent, column, consistency_level)
    self.recv_add()

  def send_add(self, key, column_parent, column, consistency_level):
    self._oprot.writeMessageBegin('add', TMessageType.CALL, self._seqid)
    args = add_args()
    args.key = key
    args.column_parent = column_parent
    args.column = column
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_add(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = add_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    return

  def remove(self, key, column_path, timestamp, consistency_level):
    """
    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.

    Parameters:
     - key
     - column_path
     - timestamp
     - consistency_level
    """
    self.send_remove(key, column_path, timestamp, consistency_level)
    self.recv_remove()

  def send_remove(self, key, column_path, timestamp, consistency_level):
    self._oprot.writeMessageBegin('remove', TMessageType.CALL, self._seqid)
    args = remove_args()
    args.key = key
    args.column_path = column_path
    args.timestamp = timestamp
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_remove(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = remove_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    return

  def remove_counter(self, key, path, consistency_level):
    """
    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.

    Parameters:
     - key
     - path
     - consistency_level
    """
    self.send_remove_counter(key, path, consistency_level)
    self.recv_remove_counter()

  def send_remove_counter(self, key, path, consistency_level):
    self._oprot.writeMessageBegin('remove_counter', TMessageType.CALL, self._seqid)
    args = remove_counter_args()
    args.key = key
    args.path = path
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_remove_counter(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = remove_counter_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    return

  def batch_mutate(self, mutation_map, consistency_level):
    """
      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.
    *

    Parameters:
     - mutation_map
     - consistency_level
    """
    self.send_batch_mutate(mutation_map, consistency_level)
    self.recv_batch_mutate()

  def send_batch_mutate(self, mutation_map, consistency_level):
    self._oprot.writeMessageBegin('batch_mutate', TMessageType.CALL, self._seqid)
    args = batch_mutate_args()
    args.mutation_map = mutation_map
    args.consistency_level = consistency_level
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_batch_mutate(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = batch_mutate_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    return

  def truncate(self, cfname):
    """
    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.

    Parameters:
     - cfname
    """
    self.send_truncate(cfname)
    self.recv_truncate()

  def send_truncate(self, cfname):
    self._oprot.writeMessageBegin('truncate', TMessageType.CALL, self._seqid)
    args = truncate_args()
    args.cfname = cfname
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_truncate(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = truncate_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    return

  def describe_schema_versions(self, ):
    """
    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.
    """
    self.send_describe_schema_versions()
    return self.recv_describe_schema_versions()

  def send_describe_schema_versions(self, ):
    self._oprot.writeMessageBegin('describe_schema_versions', TMessageType.CALL, self._seqid)
    args = describe_schema_versions_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_schema_versions(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_schema_versions_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_schema_versions failed: unknown result");

  def describe_keyspaces(self, ):
    """
    list the defined keyspaces in this cluster
    """
    self.send_describe_keyspaces()
    return self.recv_describe_keyspaces()

  def send_describe_keyspaces(self, ):
    self._oprot.writeMessageBegin('describe_keyspaces', TMessageType.CALL, self._seqid)
    args = describe_keyspaces_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_keyspaces(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_keyspaces_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_keyspaces failed: unknown result");

  def describe_cluster_name(self, ):
    """
    get the cluster name
    """
    self.send_describe_cluster_name()
    return self.recv_describe_cluster_name()

  def send_describe_cluster_name(self, ):
    self._oprot.writeMessageBegin('describe_cluster_name', TMessageType.CALL, self._seqid)
    args = describe_cluster_name_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_cluster_name(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_cluster_name_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_cluster_name failed: unknown result");

  def describe_version(self, ):
    """
    get the thrift api version
    """
    self.send_describe_version()
    return self.recv_describe_version()

  def send_describe_version(self, ):
    self._oprot.writeMessageBegin('describe_version', TMessageType.CALL, self._seqid)
    args = describe_version_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_version(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_version_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_version failed: unknown result");

  def describe_ring(self, keyspace):
    """
    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.

    Parameters:
     - keyspace
    """
    self.send_describe_ring(keyspace)
    return self.recv_describe_ring()

  def send_describe_ring(self, keyspace):
    self._oprot.writeMessageBegin('describe_ring', TMessageType.CALL, self._seqid)
    args = describe_ring_args()
    args.keyspace = keyspace
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_ring(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_ring_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_ring failed: unknown result");

  def describe_partitioner(self, ):
    """
    returns the partitioner used by this cluster
    """
    self.send_describe_partitioner()
    return self.recv_describe_partitioner()

  def send_describe_partitioner(self, ):
    self._oprot.writeMessageBegin('describe_partitioner', TMessageType.CALL, self._seqid)
    args = describe_partitioner_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_partitioner(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_partitioner_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_partitioner failed: unknown result");

  def describe_snitch(self, ):
    """
    returns the snitch used by this cluster
    """
    self.send_describe_snitch()
    return self.recv_describe_snitch()

  def send_describe_snitch(self, ):
    self._oprot.writeMessageBegin('describe_snitch', TMessageType.CALL, self._seqid)
    args = describe_snitch_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_snitch(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_snitch_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_snitch failed: unknown result");

  def describe_keyspace(self, keyspace):
    """
    describe specified keyspace

    Parameters:
     - keyspace
    """
    self.send_describe_keyspace(keyspace)
    return self.recv_describe_keyspace()

  def send_describe_keyspace(self, keyspace):
    self._oprot.writeMessageBegin('describe_keyspace', TMessageType.CALL, self._seqid)
    args = describe_keyspace_args()
    args.keyspace = keyspace
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_keyspace(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_keyspace_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.nfe is not None:
      raise result.nfe
    if result.ire is not None:
      raise result.ire
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_keyspace failed: unknown result");

  def describe_splits(self, cfName, start_token, end_token, keys_per_split):
    """
    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.

    Parameters:
     - cfName
     - start_token
     - end_token
     - keys_per_split
    """
    self.send_describe_splits(cfName, start_token, end_token, keys_per_split)
    return self.recv_describe_splits()

  def send_describe_splits(self, cfName, start_token, end_token, keys_per_split):
    self._oprot.writeMessageBegin('describe_splits', TMessageType.CALL, self._seqid)
    args = describe_splits_args()
    args.cfName = cfName
    args.start_token = start_token
    args.end_token = end_token
    args.keys_per_split = keys_per_split
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_describe_splits(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = describe_splits_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    raise TApplicationException(TApplicationException.MISSING_RESULT, "describe_splits failed: unknown result");

  def system_add_column_family(self, cf_def):
    """
    adds a column family. returns the new schema id.

    Parameters:
     - cf_def
    """
    self.send_system_add_column_family(cf_def)
    return self.recv_system_add_column_family()

  def send_system_add_column_family(self, cf_def):
    self._oprot.writeMessageBegin('system_add_column_family', TMessageType.CALL, self._seqid)
    args = system_add_column_family_args()
    args.cf_def = cf_def
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_system_add_column_family(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = system_add_column_family_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "system_add_column_family failed: unknown result");

  def system_drop_column_family(self, column_family):
    """
    drops a column family. returns the new schema id.

    Parameters:
     - column_family
    """
    self.send_system_drop_column_family(column_family)
    return self.recv_system_drop_column_family()

  def send_system_drop_column_family(self, column_family):
    self._oprot.writeMessageBegin('system_drop_column_family', TMessageType.CALL, self._seqid)
    args = system_drop_column_family_args()
    args.column_family = column_family
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_system_drop_column_family(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = system_drop_column_family_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "system_drop_column_family failed: unknown result");

  def system_add_keyspace(self, ks_def):
    """
    adds a keyspace and any column families that are part of it. returns the new schema id.

    Parameters:
     - ks_def
    """
    self.send_system_add_keyspace(ks_def)
    return self.recv_system_add_keyspace()

  def send_system_add_keyspace(self, ks_def):
    self._oprot.writeMessageBegin('system_add_keyspace', TMessageType.CALL, self._seqid)
    args = system_add_keyspace_args()
    args.ks_def = ks_def
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_system_add_keyspace(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = system_add_keyspace_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "system_add_keyspace failed: unknown result");

  def system_drop_keyspace(self, keyspace):
    """
    drops a keyspace and any column families that are part of it. returns the new schema id.

    Parameters:
     - keyspace
    """
    self.send_system_drop_keyspace(keyspace)
    return self.recv_system_drop_keyspace()

  def send_system_drop_keyspace(self, keyspace):
    self._oprot.writeMessageBegin('system_drop_keyspace', TMessageType.CALL, self._seqid)
    args = system_drop_keyspace_args()
    args.keyspace = keyspace
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_system_drop_keyspace(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = system_drop_keyspace_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "system_drop_keyspace failed: unknown result");

  def system_update_keyspace(self, ks_def):
    """
    updates properties of a keyspace. returns the new schema id.

    Parameters:
     - ks_def
    """
    self.send_system_update_keyspace(ks_def)
    return self.recv_system_update_keyspace()

  def send_system_update_keyspace(self, ks_def):
    self._oprot.writeMessageBegin('system_update_keyspace', TMessageType.CALL, self._seqid)
    args = system_update_keyspace_args()
    args.ks_def = ks_def
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_system_update_keyspace(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = system_update_keyspace_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "system_update_keyspace failed: unknown result");

  def system_update_column_family(self, cf_def):
    """
    updates properties of a column family. returns the new schema id.

    Parameters:
     - cf_def
    """
    self.send_system_update_column_family(cf_def)
    return self.recv_system_update_column_family()

  def send_system_update_column_family(self, cf_def):
    self._oprot.writeMessageBegin('system_update_column_family', TMessageType.CALL, self._seqid)
    args = system_update_column_family_args()
    args.cf_def = cf_def
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_system_update_column_family(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = system_update_column_family_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "system_update_column_family failed: unknown result");

  def execute_cql_query(self, query, compression):
    """
    Executes a CQL (Cassandra Query Language) statement and returns a
    CqlResult containing the results.

    Parameters:
     - query
     - compression
    """
    self.send_execute_cql_query(query, compression)
    return self.recv_execute_cql_query()

  def send_execute_cql_query(self, query, compression):
    self._oprot.writeMessageBegin('execute_cql_query', TMessageType.CALL, self._seqid)
    args = execute_cql_query_args()
    args.query = query
    args.compression = compression
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_execute_cql_query(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = execute_cql_query_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "execute_cql_query failed: unknown result");

  def prepare_cql_query(self, query, compression):
    """
    Prepare a CQL (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

    Parameters:
     - query
     - compression
    """
    self.send_prepare_cql_query(query, compression)
    return self.recv_prepare_cql_query()

  def send_prepare_cql_query(self, query, compression):
    self._oprot.writeMessageBegin('prepare_cql_query', TMessageType.CALL, self._seqid)
    args = prepare_cql_query_args()
    args.query = query
    args.compression = compression
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_prepare_cql_query(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = prepare_cql_query_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    raise TApplicationException(TApplicationException.MISSING_RESULT, "prepare_cql_query failed: unknown result");

  def execute_prepared_cql_query(self, itemId, values):
    """
    Executes a prepared CQL (Cassandra Query Language) statement by passing an id token and  a list of variables
    to bind and returns a CqlResult containing the results.

    Parameters:
     - itemId
     - values
    """
    self.send_execute_prepared_cql_query(itemId, values)
    return self.recv_execute_prepared_cql_query()

  def send_execute_prepared_cql_query(self, itemId, values):
    self._oprot.writeMessageBegin('execute_prepared_cql_query', TMessageType.CALL, self._seqid)
    args = execute_prepared_cql_query_args()
    args.itemId = itemId
    args.values = values
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_execute_prepared_cql_query(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = execute_prepared_cql_query_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success is not None:
      return result.success
    if result.ire is not None:
      raise result.ire
    if result.ue is not None:
      raise result.ue
    if result.te is not None:
      raise result.te
    if result.sde is not None:
      raise result.sde
    raise TApplicationException(TApplicationException.MISSING_RESULT, "execute_prepared_cql_query failed: unknown result");

  def set_cql_version(self, version):
    """
    Parameters:
     - version
    """
    self.send_set_cql_version(version)
    self.recv_set_cql_version()

  def send_set_cql_version(self, version):
    self._oprot.writeMessageBegin('set_cql_version', TMessageType.CALL, self._seqid)
    args = set_cql_version_args()
    args.version = version
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_set_cql_version(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = set_cql_version_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.ire is not None:
      raise result.ire
    return


class Processor(Iface, TProcessor):
  def __init__(self, handler):
    self._handler = handler
    self._processMap = {}
    self._processMap["login"] = Processor.process_login
    self._processMap["set_keyspace"] = Processor.process_set_keyspace
    self._processMap["get"] = Processor.process_get
    self._processMap["get_slice"] = Processor.process_get_slice
    self._processMap["get_count"] = Processor.process_get_count
    self._processMap["multiget_slice"] = Processor.process_multiget_slice
    self._processMap["multiget_count"] = Processor.process_multiget_count
    self._processMap["get_range_slices"] = Processor.process_get_range_slices
    self._processMap["get_paged_slice"] = Processor.process_get_paged_slice
    self._processMap["get_indexed_slices"] = Processor.process_get_indexed_slices
    self._processMap["insert"] = Processor.process_insert
    self._processMap["add"] = Processor.process_add
    self._processMap["remove"] = Processor.process_remove
    self._processMap["remove_counter"] = Processor.process_remove_counter
    self._processMap["batch_mutate"] = Processor.process_batch_mutate
    self._processMap["truncate"] = Processor.process_truncate
    self._processMap["describe_schema_versions"] = Processor.process_describe_schema_versions
    self._processMap["describe_keyspaces"] = Processor.process_describe_keyspaces
    self._processMap["describe_cluster_name"] = Processor.process_describe_cluster_name
    self._processMap["describe_version"] = Processor.process_describe_version
    self._processMap["describe_ring"] = Processor.process_describe_ring
    self._processMap["describe_partitioner"] = Processor.process_describe_partitioner
    self._processMap["describe_snitch"] = Processor.process_describe_snitch
    self._processMap["describe_keyspace"] = Processor.process_describe_keyspace
    self._processMap["describe_splits"] = Processor.process_describe_splits
    self._processMap["system_add_column_family"] = Processor.process_system_add_column_family
    self._processMap["system_drop_column_family"] = Processor.process_system_drop_column_family
    self._processMap["system_add_keyspace"] = Processor.process_system_add_keyspace
    self._processMap["system_drop_keyspace"] = Processor.process_system_drop_keyspace
    self._processMap["system_update_keyspace"] = Processor.process_system_update_keyspace
    self._processMap["system_update_column_family"] = Processor.process_system_update_column_family
    self._processMap["execute_cql_query"] = Processor.process_execute_cql_query
    self._processMap["prepare_cql_query"] = Processor.process_prepare_cql_query
    self._processMap["execute_prepared_cql_query"] = Processor.process_execute_prepared_cql_query
    self._processMap["set_cql_version"] = Processor.process_set_cql_version

  def process(self, iprot, oprot):
    (name, type, seqid) = iprot.readMessageBegin()
    if name not in self._processMap:
      iprot.skip(TType.STRUCT)
      iprot.readMessageEnd()
      x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
      oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
      x.write(oprot)
      oprot.writeMessageEnd()
      oprot.trans.flush()
      return
    else:
      self._processMap[name](self, seqid, iprot, oprot)
    return True

  def process_login(self, seqid, iprot, oprot):
    args = login_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = login_result()
    try:
      self._handler.login(args.auth_request)
    except AuthenticationException as authnx:
      result.authnx = authnx
    except AuthorizationException as authzx:
      result.authzx = authzx
    oprot.writeMessageBegin("login", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_set_keyspace(self, seqid, iprot, oprot):
    args = set_keyspace_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = set_keyspace_result()
    try:
      self._handler.set_keyspace(args.keyspace)
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("set_keyspace", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_get(self, seqid, iprot, oprot):
    args = get_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = get_result()
    try:
      result.success = self._handler.get(args.key, args.column_path, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except NotFoundException as nfe:
      result.nfe = nfe
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("get", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_get_slice(self, seqid, iprot, oprot):
    args = get_slice_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = get_slice_result()
    try:
      result.success = self._handler.get_slice(args.key, args.column_parent, args.predicate, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("get_slice", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_get_count(self, seqid, iprot, oprot):
    args = get_count_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = get_count_result()
    try:
      result.success = self._handler.get_count(args.key, args.column_parent, args.predicate, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("get_count", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_multiget_slice(self, seqid, iprot, oprot):
    args = multiget_slice_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = multiget_slice_result()
    try:
      result.success = self._handler.multiget_slice(args.keys, args.column_parent, args.predicate, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("multiget_slice", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_multiget_count(self, seqid, iprot, oprot):
    args = multiget_count_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = multiget_count_result()
    try:
      result.success = self._handler.multiget_count(args.keys, args.column_parent, args.predicate, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("multiget_count", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_get_range_slices(self, seqid, iprot, oprot):
    args = get_range_slices_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = get_range_slices_result()
    try:
      result.success = self._handler.get_range_slices(args.column_parent, args.predicate, args.range, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("get_range_slices", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_get_paged_slice(self, seqid, iprot, oprot):
    args = get_paged_slice_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = get_paged_slice_result()
    try:
      result.success = self._handler.get_paged_slice(args.column_family, args.range, args.start_column, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("get_paged_slice", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_get_indexed_slices(self, seqid, iprot, oprot):
    args = get_indexed_slices_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = get_indexed_slices_result()
    try:
      result.success = self._handler.get_indexed_slices(args.column_parent, args.index_clause, args.column_predicate, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("get_indexed_slices", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_insert(self, seqid, iprot, oprot):
    args = insert_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = insert_result()
    try:
      self._handler.insert(args.key, args.column_parent, args.column, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("insert", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_add(self, seqid, iprot, oprot):
    args = add_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = add_result()
    try:
      self._handler.add(args.key, args.column_parent, args.column, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("add", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_remove(self, seqid, iprot, oprot):
    args = remove_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = remove_result()
    try:
      self._handler.remove(args.key, args.column_path, args.timestamp, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("remove", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_remove_counter(self, seqid, iprot, oprot):
    args = remove_counter_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = remove_counter_result()
    try:
      self._handler.remove_counter(args.key, args.path, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("remove_counter", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_batch_mutate(self, seqid, iprot, oprot):
    args = batch_mutate_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = batch_mutate_result()
    try:
      self._handler.batch_mutate(args.mutation_map, args.consistency_level)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("batch_mutate", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_truncate(self, seqid, iprot, oprot):
    args = truncate_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = truncate_result()
    try:
      self._handler.truncate(args.cfname)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    oprot.writeMessageBegin("truncate", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_schema_versions(self, seqid, iprot, oprot):
    args = describe_schema_versions_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_schema_versions_result()
    try:
      result.success = self._handler.describe_schema_versions()
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("describe_schema_versions", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_keyspaces(self, seqid, iprot, oprot):
    args = describe_keyspaces_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_keyspaces_result()
    try:
      result.success = self._handler.describe_keyspaces()
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("describe_keyspaces", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_cluster_name(self, seqid, iprot, oprot):
    args = describe_cluster_name_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_cluster_name_result()
    result.success = self._handler.describe_cluster_name()
    oprot.writeMessageBegin("describe_cluster_name", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_version(self, seqid, iprot, oprot):
    args = describe_version_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_version_result()
    result.success = self._handler.describe_version()
    oprot.writeMessageBegin("describe_version", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_ring(self, seqid, iprot, oprot):
    args = describe_ring_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_ring_result()
    try:
      result.success = self._handler.describe_ring(args.keyspace)
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("describe_ring", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_partitioner(self, seqid, iprot, oprot):
    args = describe_partitioner_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_partitioner_result()
    result.success = self._handler.describe_partitioner()
    oprot.writeMessageBegin("describe_partitioner", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_snitch(self, seqid, iprot, oprot):
    args = describe_snitch_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_snitch_result()
    result.success = self._handler.describe_snitch()
    oprot.writeMessageBegin("describe_snitch", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_keyspace(self, seqid, iprot, oprot):
    args = describe_keyspace_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_keyspace_result()
    try:
      result.success = self._handler.describe_keyspace(args.keyspace)
    except NotFoundException as nfe:
      result.nfe = nfe
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("describe_keyspace", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_describe_splits(self, seqid, iprot, oprot):
    args = describe_splits_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = describe_splits_result()
    try:
      result.success = self._handler.describe_splits(args.cfName, args.start_token, args.end_token, args.keys_per_split)
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("describe_splits", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_system_add_column_family(self, seqid, iprot, oprot):
    args = system_add_column_family_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = system_add_column_family_result()
    try:
      result.success = self._handler.system_add_column_family(args.cf_def)
    except InvalidRequestException as ire:
      result.ire = ire
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("system_add_column_family", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_system_drop_column_family(self, seqid, iprot, oprot):
    args = system_drop_column_family_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = system_drop_column_family_result()
    try:
      result.success = self._handler.system_drop_column_family(args.column_family)
    except InvalidRequestException as ire:
      result.ire = ire
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("system_drop_column_family", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_system_add_keyspace(self, seqid, iprot, oprot):
    args = system_add_keyspace_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = system_add_keyspace_result()
    try:
      result.success = self._handler.system_add_keyspace(args.ks_def)
    except InvalidRequestException as ire:
      result.ire = ire
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("system_add_keyspace", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_system_drop_keyspace(self, seqid, iprot, oprot):
    args = system_drop_keyspace_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = system_drop_keyspace_result()
    try:
      result.success = self._handler.system_drop_keyspace(args.keyspace)
    except InvalidRequestException as ire:
      result.ire = ire
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("system_drop_keyspace", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_system_update_keyspace(self, seqid, iprot, oprot):
    args = system_update_keyspace_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = system_update_keyspace_result()
    try:
      result.success = self._handler.system_update_keyspace(args.ks_def)
    except InvalidRequestException as ire:
      result.ire = ire
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("system_update_keyspace", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_system_update_column_family(self, seqid, iprot, oprot):
    args = system_update_column_family_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = system_update_column_family_result()
    try:
      result.success = self._handler.system_update_column_family(args.cf_def)
    except InvalidRequestException as ire:
      result.ire = ire
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("system_update_column_family", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_execute_cql_query(self, seqid, iprot, oprot):
    args = execute_cql_query_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = execute_cql_query_result()
    try:
      result.success = self._handler.execute_cql_query(args.query, args.compression)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("execute_cql_query", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_prepare_cql_query(self, seqid, iprot, oprot):
    args = prepare_cql_query_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = prepare_cql_query_result()
    try:
      result.success = self._handler.prepare_cql_query(args.query, args.compression)
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("prepare_cql_query", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_execute_prepared_cql_query(self, seqid, iprot, oprot):
    args = execute_prepared_cql_query_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = execute_prepared_cql_query_result()
    try:
      result.success = self._handler.execute_prepared_cql_query(args.itemId, args.values)
    except InvalidRequestException as ire:
      result.ire = ire
    except UnavailableException as ue:
      result.ue = ue
    except TimedOutException as te:
      result.te = te
    except SchemaDisagreementException as sde:
      result.sde = sde
    oprot.writeMessageBegin("execute_prepared_cql_query", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_set_cql_version(self, seqid, iprot, oprot):
    args = set_cql_version_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = set_cql_version_result()
    try:
      self._handler.set_cql_version(args.version)
    except InvalidRequestException as ire:
      result.ire = ire
    oprot.writeMessageBegin("set_cql_version", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()


# HELPER FUNCTIONS AND STRUCTURES

class login_args:
  """
  Attributes:
   - auth_request
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'auth_request', (AuthenticationRequest, AuthenticationRequest.thrift_spec), None, ), # 1
  )

  def __init__(self, auth_request=None,):
    self.auth_request = auth_request

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.auth_request = AuthenticationRequest()
          self.auth_request.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('login_args')
    if self.auth_request is not None:
      oprot.writeFieldBegin('auth_request', TType.STRUCT, 1)
      self.auth_request.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.auth_request is None:
      raise TProtocol.TProtocolException(message='Required field auth_request is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class login_result:
  """
  Attributes:
   - authnx
   - authzx
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'authnx', (AuthenticationException, AuthenticationException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'authzx', (AuthorizationException, AuthorizationException.thrift_spec), None, ), # 2
  )

  def __init__(self, authnx=None, authzx=None,):
    self.authnx = authnx
    self.authzx = authzx

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.authnx = AuthenticationException()
          self.authnx.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.authzx = AuthorizationException()
          self.authzx.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('login_result')
    if self.authnx is not None:
      oprot.writeFieldBegin('authnx', TType.STRUCT, 1)
      self.authnx.write(oprot)
      oprot.writeFieldEnd()
    if self.authzx is not None:
      oprot.writeFieldBegin('authzx', TType.STRUCT, 2)
      self.authzx.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class set_keyspace_args:
  """
  Attributes:
   - keyspace
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'keyspace', None, None, ), # 1
  )

  def __init__(self, keyspace=None,):
    self.keyspace = keyspace

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.keyspace = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('set_keyspace_args')
    if self.keyspace is not None:
      oprot.writeFieldBegin('keyspace', TType.STRING, 1)
      oprot.writeString(self.keyspace)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keyspace is None:
      raise TProtocol.TProtocolException(message='Required field keyspace is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class set_keyspace_result:
  """
  Attributes:
   - ire
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, ire=None,):
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('set_keyspace_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_args:
  """
  Attributes:
   - key
   - column_path
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'column_path', (ColumnPath, ColumnPath.thrift_spec), None, ), # 2
    (3, TType.I32, 'consistency_level', None,     1, ), # 3
  )

  def __init__(self, key=None, column_path=None, consistency_level=thrift_spec[3][4],):
    self.key = key
    self.column_path = column_path
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_path = ColumnPath()
          self.column_path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.column_path is not None:
      oprot.writeFieldBegin('column_path', TType.STRUCT, 2)
      self.column_path.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 3)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.column_path is None:
      raise TProtocol.TProtocolException(message='Required field column_path is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_result:
  """
  Attributes:
   - success
   - ire
   - nfe
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'nfe', (NotFoundException, NotFoundException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 3
    (4, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 4
  )

  def __init__(self, success=None, ire=None, nfe=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.nfe = nfe
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = ColumnOrSuperColumn()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.nfe = NotFoundException()
          self.nfe.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.nfe is not None:
      oprot.writeFieldBegin('nfe', TType.STRUCT, 2)
      self.nfe.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 3)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 4)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_slice_args:
  """
  Attributes:
   - key
   - column_parent
   - predicate
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, key=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
    self.key = key
    self.column_parent = column_parent
    self.predicate = predicate
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.predicate = SlicePredicate()
          self.predicate.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_slice_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.predicate is not None:
      oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
      self.predicate.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.predicate is None:
      raise TProtocol.TProtocolException(message='Required field predicate is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_slice_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype171, _size168) = iprot.readListBegin()
          for _i172 in range(_size168):
            _elem173 = ColumnOrSuperColumn()
            _elem173.read(iprot)
            self.success.append(_elem173)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_slice_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter174 in self.success:
        iter174.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_count_args:
  """
  Attributes:
   - key
   - column_parent
   - predicate
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, key=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
    self.key = key
    self.column_parent = column_parent
    self.predicate = predicate
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.predicate = SlicePredicate()
          self.predicate.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_count_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.predicate is not None:
      oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
      self.predicate.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.predicate is None:
      raise TProtocol.TProtocolException(message='Required field predicate is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_count_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.I32, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.I32:
          self.success = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_count_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.I32, 0)
      oprot.writeI32(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class multiget_slice_args:
  """
  Attributes:
   - keys
   - column_parent
   - predicate
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'keys', (TType.STRING,None), None, ), # 1
    (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, keys=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
    self.keys = keys
    self.column_parent = column_parent
    self.predicate = predicate
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.LIST:
          self.keys = []
          (_etype178, _size175) = iprot.readListBegin()
          for _i179 in range(_size175):
            _elem180 = iprot.readString();
            self.keys.append(_elem180)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.predicate = SlicePredicate()
          self.predicate.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('multiget_slice_args')
    if self.keys is not None:
      oprot.writeFieldBegin('keys', TType.LIST, 1)
      oprot.writeListBegin(TType.STRING, len(self.keys))
      for iter181 in self.keys:
        oprot.writeString(iter181)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.predicate is not None:
      oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
      self.predicate.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keys is None:
      raise TProtocol.TProtocolException(message='Required field keys is unset!')
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.predicate is None:
      raise TProtocol.TProtocolException(message='Required field predicate is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class multiget_slice_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.MAP, 'success', (TType.STRING,None,TType.LIST,(TType.STRUCT,(ColumnOrSuperColumn, ColumnOrSuperColumn.thrift_spec))), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.MAP:
          self.success = {}
          (_ktype183, _vtype184, _size182 ) = iprot.readMapBegin() 
          for _i186 in range(_size182):
            _key187 = iprot.readString();
            _val188 = []
            (_etype192, _size189) = iprot.readListBegin()
            for _i193 in range(_size189):
              _elem194 = ColumnOrSuperColumn()
              _elem194.read(iprot)
              _val188.append(_elem194)
            iprot.readListEnd()
            self.success[_key187] = _val188
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('multiget_slice_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.MAP, 0)
      oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.success))
      for kiter195,viter196 in list(self.success.items()):
        oprot.writeString(kiter195)
        oprot.writeListBegin(TType.STRUCT, len(viter196))
        for iter197 in viter196:
          iter197.write(oprot)
        oprot.writeListEnd()
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class multiget_count_args:
  """
  Attributes:
   - keys
   - column_parent
   - predicate
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'keys', (TType.STRING,None), None, ), # 1
    (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, keys=None, column_parent=None, predicate=None, consistency_level=thrift_spec[4][4],):
    self.keys = keys
    self.column_parent = column_parent
    self.predicate = predicate
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.LIST:
          self.keys = []
          (_etype201, _size198) = iprot.readListBegin()
          for _i202 in range(_size198):
            _elem203 = iprot.readString();
            self.keys.append(_elem203)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.predicate = SlicePredicate()
          self.predicate.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('multiget_count_args')
    if self.keys is not None:
      oprot.writeFieldBegin('keys', TType.LIST, 1)
      oprot.writeListBegin(TType.STRING, len(self.keys))
      for iter204 in self.keys:
        oprot.writeString(iter204)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.predicate is not None:
      oprot.writeFieldBegin('predicate', TType.STRUCT, 3)
      self.predicate.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keys is None:
      raise TProtocol.TProtocolException(message='Required field keys is unset!')
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.predicate is None:
      raise TProtocol.TProtocolException(message='Required field predicate is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class multiget_count_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.MAP, 'success', (TType.STRING,None,TType.I32,None), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.MAP:
          self.success = {}
          (_ktype206, _vtype207, _size205 ) = iprot.readMapBegin() 
          for _i209 in range(_size205):
            _key210 = iprot.readString();
            _val211 = iprot.readI32();
            self.success[_key210] = _val211
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('multiget_count_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.MAP, 0)
      oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
      for kiter212,viter213 in list(self.success.items()):
        oprot.writeString(kiter212)
        oprot.writeI32(viter213)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_range_slices_args:
  """
  Attributes:
   - column_parent
   - predicate
   - range
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'range', (KeyRange, KeyRange.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, column_parent=None, predicate=None, range=None, consistency_level=thrift_spec[4][4],):
    self.column_parent = column_parent
    self.predicate = predicate
    self.range = range
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.predicate = SlicePredicate()
          self.predicate.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.range = KeyRange()
          self.range.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_range_slices_args')
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 1)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.predicate is not None:
      oprot.writeFieldBegin('predicate', TType.STRUCT, 2)
      self.predicate.write(oprot)
      oprot.writeFieldEnd()
    if self.range is not None:
      oprot.writeFieldBegin('range', TType.STRUCT, 3)
      self.range.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.predicate is None:
      raise TProtocol.TProtocolException(message='Required field predicate is unset!')
    if self.range is None:
      raise TProtocol.TProtocolException(message='Required field range is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_range_slices_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(KeySlice, KeySlice.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype217, _size214) = iprot.readListBegin()
          for _i218 in range(_size214):
            _elem219 = KeySlice()
            _elem219.read(iprot)
            self.success.append(_elem219)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_range_slices_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter220 in self.success:
        iter220.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_paged_slice_args:
  """
  Attributes:
   - column_family
   - range
   - start_column
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'column_family', None, None, ), # 1
    (2, TType.STRUCT, 'range', (KeyRange, KeyRange.thrift_spec), None, ), # 2
    (3, TType.STRING, 'start_column', None, None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, column_family=None, range=None, start_column=None, consistency_level=thrift_spec[4][4],):
    self.column_family = column_family
    self.range = range
    self.start_column = start_column
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.column_family = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.range = KeyRange()
          self.range.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.start_column = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_paged_slice_args')
    if self.column_family is not None:
      oprot.writeFieldBegin('column_family', TType.STRING, 1)
      oprot.writeString(self.column_family)
      oprot.writeFieldEnd()
    if self.range is not None:
      oprot.writeFieldBegin('range', TType.STRUCT, 2)
      self.range.write(oprot)
      oprot.writeFieldEnd()
    if self.start_column is not None:
      oprot.writeFieldBegin('start_column', TType.STRING, 3)
      oprot.writeString(self.start_column)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_family is None:
      raise TProtocol.TProtocolException(message='Required field column_family is unset!')
    if self.range is None:
      raise TProtocol.TProtocolException(message='Required field range is unset!')
    if self.start_column is None:
      raise TProtocol.TProtocolException(message='Required field start_column is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_paged_slice_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(KeySlice, KeySlice.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype224, _size221) = iprot.readListBegin()
          for _i225 in range(_size221):
            _elem226 = KeySlice()
            _elem226.read(iprot)
            self.success.append(_elem226)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_paged_slice_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter227 in self.success:
        iter227.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_indexed_slices_args:
  """
  Attributes:
   - column_parent
   - index_clause
   - column_predicate
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'index_clause', (IndexClause, IndexClause.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'column_predicate', (SlicePredicate, SlicePredicate.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, column_parent=None, index_clause=None, column_predicate=None, consistency_level=thrift_spec[4][4],):
    self.column_parent = column_parent
    self.index_clause = index_clause
    self.column_predicate = column_predicate
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.index_clause = IndexClause()
          self.index_clause.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.column_predicate = SlicePredicate()
          self.column_predicate.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_indexed_slices_args')
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 1)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.index_clause is not None:
      oprot.writeFieldBegin('index_clause', TType.STRUCT, 2)
      self.index_clause.write(oprot)
      oprot.writeFieldEnd()
    if self.column_predicate is not None:
      oprot.writeFieldBegin('column_predicate', TType.STRUCT, 3)
      self.column_predicate.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.index_clause is None:
      raise TProtocol.TProtocolException(message='Required field index_clause is unset!')
    if self.column_predicate is None:
      raise TProtocol.TProtocolException(message='Required field column_predicate is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class get_indexed_slices_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(KeySlice, KeySlice.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, success=None, ire=None, ue=None, te=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype231, _size228) = iprot.readListBegin()
          for _i232 in range(_size228):
            _elem233 = KeySlice()
            _elem233.read(iprot)
            self.success.append(_elem233)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('get_indexed_slices_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter234 in self.success:
        iter234.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class insert_args:
  """
  Attributes:
   - key
   - column_parent
   - column
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'column', (Column, Column.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, key=None, column_parent=None, column=None, consistency_level=thrift_spec[4][4],):
    self.key = key
    self.column_parent = column_parent
    self.column = column
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.column = Column()
          self.column.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('insert_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.column is not None:
      oprot.writeFieldBegin('column', TType.STRUCT, 3)
      self.column.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.column is None:
      raise TProtocol.TProtocolException(message='Required field column is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class insert_result:
  """
  Attributes:
   - ire
   - ue
   - te
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, ire=None, ue=None, te=None,):
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('insert_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class add_args:
  """
  Attributes:
   - key
   - column_parent
   - column
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'column_parent', (ColumnParent, ColumnParent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'column', (CounterColumn, CounterColumn.thrift_spec), None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, key=None, column_parent=None, column=None, consistency_level=thrift_spec[4][4],):
    self.key = key
    self.column_parent = column_parent
    self.column = column
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_parent = ColumnParent()
          self.column_parent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.column = CounterColumn()
          self.column.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('add_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.column_parent is not None:
      oprot.writeFieldBegin('column_parent', TType.STRUCT, 2)
      self.column_parent.write(oprot)
      oprot.writeFieldEnd()
    if self.column is not None:
      oprot.writeFieldBegin('column', TType.STRUCT, 3)
      self.column.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.column_parent is None:
      raise TProtocol.TProtocolException(message='Required field column_parent is unset!')
    if self.column is None:
      raise TProtocol.TProtocolException(message='Required field column is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class add_result:
  """
  Attributes:
   - ire
   - ue
   - te
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, ire=None, ue=None, te=None,):
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('add_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class remove_args:
  """
  Attributes:
   - key
   - column_path
   - timestamp
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'column_path', (ColumnPath, ColumnPath.thrift_spec), None, ), # 2
    (3, TType.I64, 'timestamp', None, None, ), # 3
    (4, TType.I32, 'consistency_level', None,     1, ), # 4
  )

  def __init__(self, key=None, column_path=None, timestamp=None, consistency_level=thrift_spec[4][4],):
    self.key = key
    self.column_path = column_path
    self.timestamp = timestamp
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.column_path = ColumnPath()
          self.column_path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I64:
          self.timestamp = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('remove_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.column_path is not None:
      oprot.writeFieldBegin('column_path', TType.STRUCT, 2)
      self.column_path.write(oprot)
      oprot.writeFieldEnd()
    if self.timestamp is not None:
      oprot.writeFieldBegin('timestamp', TType.I64, 3)
      oprot.writeI64(self.timestamp)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 4)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.column_path is None:
      raise TProtocol.TProtocolException(message='Required field column_path is unset!')
    if self.timestamp is None:
      raise TProtocol.TProtocolException(message='Required field timestamp is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class remove_result:
  """
  Attributes:
   - ire
   - ue
   - te
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, ire=None, ue=None, te=None,):
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('remove_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class remove_counter_args:
  """
  Attributes:
   - key
   - path
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'key', None, None, ), # 1
    (2, TType.STRUCT, 'path', (ColumnPath, ColumnPath.thrift_spec), None, ), # 2
    (3, TType.I32, 'consistency_level', None,     1, ), # 3
  )

  def __init__(self, key=None, path=None, consistency_level=thrift_spec[3][4],):
    self.key = key
    self.path = path
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.key = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.path = ColumnPath()
          self.path.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('remove_counter_args')
    if self.key is not None:
      oprot.writeFieldBegin('key', TType.STRING, 1)
      oprot.writeString(self.key)
      oprot.writeFieldEnd()
    if self.path is not None:
      oprot.writeFieldBegin('path', TType.STRUCT, 2)
      self.path.write(oprot)
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 3)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.key is None:
      raise TProtocol.TProtocolException(message='Required field key is unset!')
    if self.path is None:
      raise TProtocol.TProtocolException(message='Required field path is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class remove_counter_result:
  """
  Attributes:
   - ire
   - ue
   - te
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, ire=None, ue=None, te=None,):
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('remove_counter_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class batch_mutate_args:
  """
  Attributes:
   - mutation_map
   - consistency_level
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'mutation_map', (TType.STRING,None,TType.MAP,(TType.STRING,None,TType.LIST,(TType.STRUCT,(Mutation, Mutation.thrift_spec)))), None, ), # 1
    (2, TType.I32, 'consistency_level', None,     1, ), # 2
  )

  def __init__(self, mutation_map=None, consistency_level=thrift_spec[2][4],):
    self.mutation_map = mutation_map
    self.consistency_level = consistency_level

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.MAP:
          self.mutation_map = {}
          (_ktype236, _vtype237, _size235 ) = iprot.readMapBegin() 
          for _i239 in range(_size235):
            _key240 = iprot.readString();
            _val241 = {}
            (_ktype243, _vtype244, _size242 ) = iprot.readMapBegin() 
            for _i246 in range(_size242):
              _key247 = iprot.readString();
              _val248 = []
              (_etype252, _size249) = iprot.readListBegin()
              for _i253 in range(_size249):
                _elem254 = Mutation()
                _elem254.read(iprot)
                _val248.append(_elem254)
              iprot.readListEnd()
              _val241[_key247] = _val248
            iprot.readMapEnd()
            self.mutation_map[_key240] = _val241
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.consistency_level = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('batch_mutate_args')
    if self.mutation_map is not None:
      oprot.writeFieldBegin('mutation_map', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.MAP, len(self.mutation_map))
      for kiter255,viter256 in list(self.mutation_map.items()):
        oprot.writeString(kiter255)
        oprot.writeMapBegin(TType.STRING, TType.LIST, len(viter256))
        for kiter257,viter258 in list(viter256.items()):
          oprot.writeString(kiter257)
          oprot.writeListBegin(TType.STRUCT, len(viter258))
          for iter259 in viter258:
            iter259.write(oprot)
          oprot.writeListEnd()
        oprot.writeMapEnd()
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.consistency_level is not None:
      oprot.writeFieldBegin('consistency_level', TType.I32, 2)
      oprot.writeI32(self.consistency_level)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.mutation_map is None:
      raise TProtocol.TProtocolException(message='Required field mutation_map is unset!')
    if self.consistency_level is None:
      raise TProtocol.TProtocolException(message='Required field consistency_level is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class batch_mutate_result:
  """
  Attributes:
   - ire
   - ue
   - te
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, ire=None, ue=None, te=None,):
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('batch_mutate_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class truncate_args:
  """
  Attributes:
   - cfname
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'cfname', None, None, ), # 1
  )

  def __init__(self, cfname=None,):
    self.cfname = cfname

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.cfname = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('truncate_args')
    if self.cfname is not None:
      oprot.writeFieldBegin('cfname', TType.STRING, 1)
      oprot.writeString(self.cfname)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.cfname is None:
      raise TProtocol.TProtocolException(message='Required field cfname is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class truncate_result:
  """
  Attributes:
   - ire
   - ue
   - te
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
  )

  def __init__(self, ire=None, ue=None, te=None,):
    self.ire = ire
    self.ue = ue
    self.te = te

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('truncate_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_schema_versions_args:

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_schema_versions_args')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_schema_versions_result:
  """
  Attributes:
   - success
   - ire
  """

  thrift_spec = (
    (0, TType.MAP, 'success', (TType.STRING,None,TType.LIST,(TType.STRING,None)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, ire=None,):
    self.success = success
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.MAP:
          self.success = {}
          (_ktype261, _vtype262, _size260 ) = iprot.readMapBegin() 
          for _i264 in range(_size260):
            _key265 = iprot.readString();
            _val266 = []
            (_etype270, _size267) = iprot.readListBegin()
            for _i271 in range(_size267):
              _elem272 = iprot.readString();
              _val266.append(_elem272)
            iprot.readListEnd()
            self.success[_key265] = _val266
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_schema_versions_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.MAP, 0)
      oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.success))
      for kiter273,viter274 in list(self.success.items()):
        oprot.writeString(kiter273)
        oprot.writeListBegin(TType.STRING, len(viter274))
        for iter275 in viter274:
          oprot.writeString(iter275)
        oprot.writeListEnd()
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_keyspaces_args:

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_keyspaces_args')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_keyspaces_result:
  """
  Attributes:
   - success
   - ire
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(KsDef, KsDef.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, ire=None,):
    self.success = success
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype279, _size276) = iprot.readListBegin()
          for _i280 in range(_size276):
            _elem281 = KsDef()
            _elem281.read(iprot)
            self.success.append(_elem281)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_keyspaces_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter282 in self.success:
        iter282.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_cluster_name_args:

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_cluster_name_args')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_cluster_name_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

  def __init__(self, success=None,):
    self.success = success

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_cluster_name_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_version_args:

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_version_args')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_version_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

  def __init__(self, success=None,):
    self.success = success

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_version_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_ring_args:
  """
  Attributes:
   - keyspace
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'keyspace', None, None, ), # 1
  )

  def __init__(self, keyspace=None,):
    self.keyspace = keyspace

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.keyspace = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_ring_args')
    if self.keyspace is not None:
      oprot.writeFieldBegin('keyspace', TType.STRING, 1)
      oprot.writeString(self.keyspace)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keyspace is None:
      raise TProtocol.TProtocolException(message='Required field keyspace is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_ring_result:
  """
  Attributes:
   - success
   - ire
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT,(TokenRange, TokenRange.thrift_spec)), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, ire=None,):
    self.success = success
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype286, _size283) = iprot.readListBegin()
          for _i287 in range(_size283):
            _elem288 = TokenRange()
            _elem288.read(iprot)
            self.success.append(_elem288)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_ring_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRUCT, len(self.success))
      for iter289 in self.success:
        iter289.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_partitioner_args:

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_partitioner_args')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_partitioner_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

  def __init__(self, success=None,):
    self.success = success

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_partitioner_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_snitch_args:

  thrift_spec = (
  )

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_snitch_args')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_snitch_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

  def __init__(self, success=None,):
    self.success = success

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_snitch_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_keyspace_args:
  """
  Attributes:
   - keyspace
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'keyspace', None, None, ), # 1
  )

  def __init__(self, keyspace=None,):
    self.keyspace = keyspace

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.keyspace = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_keyspace_args')
    if self.keyspace is not None:
      oprot.writeFieldBegin('keyspace', TType.STRING, 1)
      oprot.writeString(self.keyspace)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keyspace is None:
      raise TProtocol.TProtocolException(message='Required field keyspace is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_keyspace_result:
  """
  Attributes:
   - success
   - nfe
   - ire
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (KsDef, KsDef.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'nfe', (NotFoundException, NotFoundException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, nfe=None, ire=None,):
    self.success = success
    self.nfe = nfe
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = KsDef()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.nfe = NotFoundException()
          self.nfe.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_keyspace_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.nfe is not None:
      oprot.writeFieldBegin('nfe', TType.STRUCT, 1)
      self.nfe.write(oprot)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 2)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_splits_args:
  """
  Attributes:
   - cfName
   - start_token
   - end_token
   - keys_per_split
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'cfName', None, None, ), # 1
    (2, TType.STRING, 'start_token', None, None, ), # 2
    (3, TType.STRING, 'end_token', None, None, ), # 3
    (4, TType.I32, 'keys_per_split', None, None, ), # 4
  )

  def __init__(self, cfName=None, start_token=None, end_token=None, keys_per_split=None,):
    self.cfName = cfName
    self.start_token = start_token
    self.end_token = end_token
    self.keys_per_split = keys_per_split

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.cfName = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.start_token = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.end_token = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.keys_per_split = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_splits_args')
    if self.cfName is not None:
      oprot.writeFieldBegin('cfName', TType.STRING, 1)
      oprot.writeString(self.cfName)
      oprot.writeFieldEnd()
    if self.start_token is not None:
      oprot.writeFieldBegin('start_token', TType.STRING, 2)
      oprot.writeString(self.start_token)
      oprot.writeFieldEnd()
    if self.end_token is not None:
      oprot.writeFieldBegin('end_token', TType.STRING, 3)
      oprot.writeString(self.end_token)
      oprot.writeFieldEnd()
    if self.keys_per_split is not None:
      oprot.writeFieldBegin('keys_per_split', TType.I32, 4)
      oprot.writeI32(self.keys_per_split)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.cfName is None:
      raise TProtocol.TProtocolException(message='Required field cfName is unset!')
    if self.start_token is None:
      raise TProtocol.TProtocolException(message='Required field start_token is unset!')
    if self.end_token is None:
      raise TProtocol.TProtocolException(message='Required field end_token is unset!')
    if self.keys_per_split is None:
      raise TProtocol.TProtocolException(message='Required field keys_per_split is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class describe_splits_result:
  """
  Attributes:
   - success
   - ire
  """

  thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRING,None), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, ire=None,):
    self.success = success
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.LIST:
          self.success = []
          (_etype293, _size290) = iprot.readListBegin()
          for _i294 in range(_size290):
            _elem295 = iprot.readString();
            self.success.append(_elem295)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('describe_splits_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.LIST, 0)
      oprot.writeListBegin(TType.STRING, len(self.success))
      for iter296 in self.success:
        oprot.writeString(iter296)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_add_column_family_args:
  """
  Attributes:
   - cf_def
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'cf_def', (CfDef, CfDef.thrift_spec), None, ), # 1
  )

  def __init__(self, cf_def=None,):
    self.cf_def = cf_def

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.cf_def = CfDef()
          self.cf_def.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_add_column_family_args')
    if self.cf_def is not None:
      oprot.writeFieldBegin('cf_def', TType.STRUCT, 1)
      self.cf_def.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.cf_def is None:
      raise TProtocol.TProtocolException(message='Required field cf_def is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_add_column_family_result:
  """
  Attributes:
   - success
   - ire
   - sde
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, ire=None, sde=None,):
    self.success = success
    self.ire = ire
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_add_column_family_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 2)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_drop_column_family_args:
  """
  Attributes:
   - column_family
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'column_family', None, None, ), # 1
  )

  def __init__(self, column_family=None,):
    self.column_family = column_family

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.column_family = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_drop_column_family_args')
    if self.column_family is not None:
      oprot.writeFieldBegin('column_family', TType.STRING, 1)
      oprot.writeString(self.column_family)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.column_family is None:
      raise TProtocol.TProtocolException(message='Required field column_family is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_drop_column_family_result:
  """
  Attributes:
   - success
   - ire
   - sde
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, ire=None, sde=None,):
    self.success = success
    self.ire = ire
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_drop_column_family_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 2)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_add_keyspace_args:
  """
  Attributes:
   - ks_def
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ks_def', (KsDef, KsDef.thrift_spec), None, ), # 1
  )

  def __init__(self, ks_def=None,):
    self.ks_def = ks_def

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ks_def = KsDef()
          self.ks_def.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_add_keyspace_args')
    if self.ks_def is not None:
      oprot.writeFieldBegin('ks_def', TType.STRUCT, 1)
      self.ks_def.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.ks_def is None:
      raise TProtocol.TProtocolException(message='Required field ks_def is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_add_keyspace_result:
  """
  Attributes:
   - success
   - ire
   - sde
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, ire=None, sde=None,):
    self.success = success
    self.ire = ire
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_add_keyspace_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 2)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_drop_keyspace_args:
  """
  Attributes:
   - keyspace
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'keyspace', None, None, ), # 1
  )

  def __init__(self, keyspace=None,):
    self.keyspace = keyspace

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.keyspace = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_drop_keyspace_args')
    if self.keyspace is not None:
      oprot.writeFieldBegin('keyspace', TType.STRING, 1)
      oprot.writeString(self.keyspace)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.keyspace is None:
      raise TProtocol.TProtocolException(message='Required field keyspace is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_drop_keyspace_result:
  """
  Attributes:
   - success
   - ire
   - sde
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, ire=None, sde=None,):
    self.success = success
    self.ire = ire
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_drop_keyspace_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 2)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_update_keyspace_args:
  """
  Attributes:
   - ks_def
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ks_def', (KsDef, KsDef.thrift_spec), None, ), # 1
  )

  def __init__(self, ks_def=None,):
    self.ks_def = ks_def

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ks_def = KsDef()
          self.ks_def.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_update_keyspace_args')
    if self.ks_def is not None:
      oprot.writeFieldBegin('ks_def', TType.STRUCT, 1)
      self.ks_def.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.ks_def is None:
      raise TProtocol.TProtocolException(message='Required field ks_def is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_update_keyspace_result:
  """
  Attributes:
   - success
   - ire
   - sde
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, ire=None, sde=None,):
    self.success = success
    self.ire = ire
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_update_keyspace_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 2)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_update_column_family_args:
  """
  Attributes:
   - cf_def
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'cf_def', (CfDef, CfDef.thrift_spec), None, ), # 1
  )

  def __init__(self, cf_def=None,):
    self.cf_def = cf_def

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.cf_def = CfDef()
          self.cf_def.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_update_column_family_args')
    if self.cf_def is not None:
      oprot.writeFieldBegin('cf_def', TType.STRUCT, 1)
      self.cf_def.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.cf_def is None:
      raise TProtocol.TProtocolException(message='Required field cf_def is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class system_update_column_family_result:
  """
  Attributes:
   - success
   - ire
   - sde
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 2
  )

  def __init__(self, success=None, ire=None, sde=None,):
    self.success = success
    self.ire = ire
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('system_update_column_family_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 2)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class execute_cql_query_args:
  """
  Attributes:
   - query
   - compression
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'query', None, None, ), # 1
    (2, TType.I32, 'compression', None, None, ), # 2
  )

  def __init__(self, query=None, compression=None,):
    self.query = query
    self.compression = compression

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.query = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.compression = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('execute_cql_query_args')
    if self.query is not None:
      oprot.writeFieldBegin('query', TType.STRING, 1)
      oprot.writeString(self.query)
      oprot.writeFieldEnd()
    if self.compression is not None:
      oprot.writeFieldBegin('compression', TType.I32, 2)
      oprot.writeI32(self.compression)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.query is None:
      raise TProtocol.TProtocolException(message='Required field query is unset!')
    if self.compression is None:
      raise TProtocol.TProtocolException(message='Required field compression is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class execute_cql_query_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
   - sde
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (CqlResult, CqlResult.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
    (4, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 4
  )

  def __init__(self, success=None, ire=None, ue=None, te=None, sde=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = CqlResult()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('execute_cql_query_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 4)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class prepare_cql_query_args:
  """
  Attributes:
   - query
   - compression
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'query', None, None, ), # 1
    (2, TType.I32, 'compression', None, None, ), # 2
  )

  def __init__(self, query=None, compression=None,):
    self.query = query
    self.compression = compression

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.query = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.compression = iprot.readI32();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('prepare_cql_query_args')
    if self.query is not None:
      oprot.writeFieldBegin('query', TType.STRING, 1)
      oprot.writeString(self.query)
      oprot.writeFieldEnd()
    if self.compression is not None:
      oprot.writeFieldBegin('compression', TType.I32, 2)
      oprot.writeI32(self.compression)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.query is None:
      raise TProtocol.TProtocolException(message='Required field query is unset!')
    if self.compression is None:
      raise TProtocol.TProtocolException(message='Required field compression is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class prepare_cql_query_result:
  """
  Attributes:
   - success
   - ire
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (CqlPreparedResult, CqlPreparedResult.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, ire=None,):
    self.success = success
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = CqlPreparedResult()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('prepare_cql_query_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class execute_prepared_cql_query_args:
  """
  Attributes:
   - itemId
   - values
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'itemId', None, None, ), # 1
    (2, TType.LIST, 'values', (TType.STRING,None), None, ), # 2
  )

  def __init__(self, itemId=None, values=None,):
    self.itemId = itemId
    self.values = values

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.I32:
          self.itemId = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.values = []
          (_etype300, _size297) = iprot.readListBegin()
          for _i301 in range(_size297):
            _elem302 = iprot.readString();
            self.values.append(_elem302)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('execute_prepared_cql_query_args')
    if self.itemId is not None:
      oprot.writeFieldBegin('itemId', TType.I32, 1)
      oprot.writeI32(self.itemId)
      oprot.writeFieldEnd()
    if self.values is not None:
      oprot.writeFieldBegin('values', TType.LIST, 2)
      oprot.writeListBegin(TType.STRING, len(self.values))
      for iter303 in self.values:
        oprot.writeString(iter303)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.itemId is None:
      raise TProtocol.TProtocolException(message='Required field itemId is unset!')
    if self.values is None:
      raise TProtocol.TProtocolException(message='Required field values is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class execute_prepared_cql_query_result:
  """
  Attributes:
   - success
   - ire
   - ue
   - te
   - sde
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (CqlResult, CqlResult.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ue', (UnavailableException, UnavailableException.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'te', (TimedOutException, TimedOutException.thrift_spec), None, ), # 3
    (4, TType.STRUCT, 'sde', (SchemaDisagreementException, SchemaDisagreementException.thrift_spec), None, ), # 4
  )

  def __init__(self, success=None, ire=None, ue=None, te=None, sde=None,):
    self.success = success
    self.ire = ire
    self.ue = ue
    self.te = te
    self.sde = sde

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = CqlResult()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ue = UnavailableException()
          self.ue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.te = TimedOutException()
          self.te.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.sde = SchemaDisagreementException()
          self.sde.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('execute_prepared_cql_query_result')
    if self.success is not None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    if self.ue is not None:
      oprot.writeFieldBegin('ue', TType.STRUCT, 2)
      self.ue.write(oprot)
      oprot.writeFieldEnd()
    if self.te is not None:
      oprot.writeFieldBegin('te', TType.STRUCT, 3)
      self.te.write(oprot)
      oprot.writeFieldEnd()
    if self.sde is not None:
      oprot.writeFieldBegin('sde', TType.STRUCT, 4)
      self.sde.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class set_cql_version_args:
  """
  Attributes:
   - version
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'version', None, None, ), # 1
  )

  def __init__(self, version=None,):
    self.version = version

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRING:
          self.version = iprot.readString();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('set_cql_version_args')
    if self.version is not None:
      oprot.writeFieldBegin('version', TType.STRING, 1)
      oprot.writeString(self.version)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.version is None:
      raise TProtocol.TProtocolException(message='Required field version is unset!')
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)

class set_cql_version_result:
  """
  Attributes:
   - ire
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'ire', (InvalidRequestException, InvalidRequestException.thrift_spec), None, ), # 1
  )

  def __init__(self, ire=None,):
    self.ire = ire

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 1:
        if ftype == TType.STRUCT:
          self.ire = InvalidRequestException()
          self.ire.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('set_cql_version_result')
    if self.ire is not None:
      oprot.writeFieldBegin('ire', TType.STRUCT, 1)
      self.ire.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.items()]
    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

  def __eq__(self, other):
    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

  def __ne__(self, other):
    return not (self == other)
