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

from thrift.Thrift import TType, TMessageType, TException, TApplicationException

from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol, TProtocol
try:
  from thrift.protocol import fastbinary
except:
  fastbinary = None


class PartialKey:
  ROW = 0
  ROW_COLFAM = 1
  ROW_COLFAM_COLQUAL = 2
  ROW_COLFAM_COLQUAL_COLVIS = 3
  ROW_COLFAM_COLQUAL_COLVIS_TIME = 4
  ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL = 5

  _VALUES_TO_NAMES = {
    0: "ROW",
    1: "ROW_COLFAM",
    2: "ROW_COLFAM_COLQUAL",
    3: "ROW_COLFAM_COLQUAL_COLVIS",
    4: "ROW_COLFAM_COLQUAL_COLVIS_TIME",
    5: "ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL",
  }

  _NAMES_TO_VALUES = {
    "ROW": 0,
    "ROW_COLFAM": 1,
    "ROW_COLFAM_COLQUAL": 2,
    "ROW_COLFAM_COLQUAL_COLVIS": 3,
    "ROW_COLFAM_COLQUAL_COLVIS_TIME": 4,
    "ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL": 5,
  }

class TablePermission:
  READ = 2
  WRITE = 3
  BULK_IMPORT = 4
  ALTER_TABLE = 5
  GRANT = 6
  DROP_TABLE = 7

  _VALUES_TO_NAMES = {
    2: "READ",
    3: "WRITE",
    4: "BULK_IMPORT",
    5: "ALTER_TABLE",
    6: "GRANT",
    7: "DROP_TABLE",
  }

  _NAMES_TO_VALUES = {
    "READ": 2,
    "WRITE": 3,
    "BULK_IMPORT": 4,
    "ALTER_TABLE": 5,
    "GRANT": 6,
    "DROP_TABLE": 7,
  }

class SystemPermission:
  GRANT = 0
  CREATE_TABLE = 1
  DROP_TABLE = 2
  ALTER_TABLE = 3
  CREATE_USER = 4
  DROP_USER = 5
  ALTER_USER = 6
  SYSTEM = 7
  CREATE_NAMESPACE = 8
  DROP_NAMESPACE = 9
  ALTER_NAMESPACE = 10
  OBTAIN_DELEGATION_TOKEN = 11

  _VALUES_TO_NAMES = {
    0: "GRANT",
    1: "CREATE_TABLE",
    2: "DROP_TABLE",
    3: "ALTER_TABLE",
    4: "CREATE_USER",
    5: "DROP_USER",
    6: "ALTER_USER",
    7: "SYSTEM",
    8: "CREATE_NAMESPACE",
    9: "DROP_NAMESPACE",
    10: "ALTER_NAMESPACE",
    11: "OBTAIN_DELEGATION_TOKEN",
  }

  _NAMES_TO_VALUES = {
    "GRANT": 0,
    "CREATE_TABLE": 1,
    "DROP_TABLE": 2,
    "ALTER_TABLE": 3,
    "CREATE_USER": 4,
    "DROP_USER": 5,
    "ALTER_USER": 6,
    "SYSTEM": 7,
    "CREATE_NAMESPACE": 8,
    "DROP_NAMESPACE": 9,
    "ALTER_NAMESPACE": 10,
    "OBTAIN_DELEGATION_TOKEN": 11,
  }

class ScanType:
  SINGLE = 0
  BATCH = 1

  _VALUES_TO_NAMES = {
    0: "SINGLE",
    1: "BATCH",
  }

  _NAMES_TO_VALUES = {
    "SINGLE": 0,
    "BATCH": 1,
  }

class ScanState:
  IDLE = 0
  RUNNING = 1
  QUEUED = 2

  _VALUES_TO_NAMES = {
    0: "IDLE",
    1: "RUNNING",
    2: "QUEUED",
  }

  _NAMES_TO_VALUES = {
    "IDLE": 0,
    "RUNNING": 1,
    "QUEUED": 2,
  }

class ConditionalStatus:
  ACCEPTED = 0
  REJECTED = 1
  VIOLATED = 2
  UNKNOWN = 3
  INVISIBLE_VISIBILITY = 4

  _VALUES_TO_NAMES = {
    0: "ACCEPTED",
    1: "REJECTED",
    2: "VIOLATED",
    3: "UNKNOWN",
    4: "INVISIBLE_VISIBILITY",
  }

  _NAMES_TO_VALUES = {
    "ACCEPTED": 0,
    "REJECTED": 1,
    "VIOLATED": 2,
    "UNKNOWN": 3,
    "INVISIBLE_VISIBILITY": 4,
  }

class Durability:
  DEFAULT = 0
  NONE = 1
  LOG = 2
  FLUSH = 3
  SYNC = 4

  _VALUES_TO_NAMES = {
    0: "DEFAULT",
    1: "NONE",
    2: "LOG",
    3: "FLUSH",
    4: "SYNC",
  }

  _NAMES_TO_VALUES = {
    "DEFAULT": 0,
    "NONE": 1,
    "LOG": 2,
    "FLUSH": 3,
    "SYNC": 4,
  }

class CompactionType:
  MINOR = 0
  MERGE = 1
  MAJOR = 2
  FULL = 3

  _VALUES_TO_NAMES = {
    0: "MINOR",
    1: "MERGE",
    2: "MAJOR",
    3: "FULL",
  }

  _NAMES_TO_VALUES = {
    "MINOR": 0,
    "MERGE": 1,
    "MAJOR": 2,
    "FULL": 3,
  }

class CompactionReason:
  USER = 0
  SYSTEM = 1
  CHOP = 2
  IDLE = 3
  CLOSE = 4

  _VALUES_TO_NAMES = {
    0: "USER",
    1: "SYSTEM",
    2: "CHOP",
    3: "IDLE",
    4: "CLOSE",
  }

  _NAMES_TO_VALUES = {
    "USER": 0,
    "SYSTEM": 1,
    "CHOP": 2,
    "IDLE": 3,
    "CLOSE": 4,
  }

class IteratorScope:
  MINC = 0
  MAJC = 1
  SCAN = 2

  _VALUES_TO_NAMES = {
    0: "MINC",
    1: "MAJC",
    2: "SCAN",
  }

  _NAMES_TO_VALUES = {
    "MINC": 0,
    "MAJC": 1,
    "SCAN": 2,
  }

class TimeType:
  LOGICAL = 0
  MILLIS = 1

  _VALUES_TO_NAMES = {
    0: "LOGICAL",
    1: "MILLIS",
  }

  _NAMES_TO_VALUES = {
    "LOGICAL": 0,
    "MILLIS": 1,
  }


class Key:
  """
  Attributes:
   - row
   - colFamily
   - colQualifier
   - colVisibility
   - timestamp
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'row', None, None, ), # 1
    (2, TType.STRING, 'colFamily', None, None, ), # 2
    (3, TType.STRING, 'colQualifier', None, None, ), # 3
    (4, TType.STRING, 'colVisibility', None, None, ), # 4
    (5, TType.I64, 'timestamp', None, 9223372036854775807, ), # 5
  )

  def __init__(self, row=None, colFamily=None, colQualifier=None, colVisibility=None, timestamp=thrift_spec[5][4],):
    self.row = row
    self.colFamily = colFamily
    self.colQualifier = colQualifier
    self.colVisibility = colVisibility
    self.timestamp = timestamp

  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.row = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.colFamily = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.colQualifier = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.colVisibility = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I64:
          self.timestamp = iprot.readI64();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('Key')
    if self.row is not None:
      oprot.writeFieldBegin('row', TType.STRING, 1)
      oprot.writeString(self.row)
      oprot.writeFieldEnd()
    if self.colFamily is not None:
      oprot.writeFieldBegin('colFamily', TType.STRING, 2)
      oprot.writeString(self.colFamily)
      oprot.writeFieldEnd()
    if self.colQualifier is not None:
      oprot.writeFieldBegin('colQualifier', TType.STRING, 3)
      oprot.writeString(self.colQualifier)
      oprot.writeFieldEnd()
    if self.colVisibility is not None:
      oprot.writeFieldBegin('colVisibility', TType.STRING, 4)
      oprot.writeString(self.colVisibility)
      oprot.writeFieldEnd()
    if self.timestamp is not None:
      oprot.writeFieldBegin('timestamp', TType.I64, 5)
      oprot.writeI64(self.timestamp)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ColumnUpdate:
  """
  Attributes:
   - colFamily
   - colQualifier
   - colVisibility
   - timestamp
   - value
   - deleteCell
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'colFamily', None, None, ), # 1
    (2, TType.STRING, 'colQualifier', None, None, ), # 2
    (3, TType.STRING, 'colVisibility', None, None, ), # 3
    (4, TType.I64, 'timestamp', None, None, ), # 4
    (5, TType.STRING, 'value', None, None, ), # 5
    (6, TType.BOOL, 'deleteCell', None, None, ), # 6
  )

  def __init__(self, colFamily=None, colQualifier=None, colVisibility=None, timestamp=None, value=None, deleteCell=None,):
    self.colFamily = colFamily
    self.colQualifier = colQualifier
    self.colVisibility = colVisibility
    self.timestamp = timestamp
    self.value = value
    self.deleteCell = deleteCell

  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.colFamily = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.colQualifier = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.colVisibility = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I64:
          self.timestamp = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.STRING:
          self.value = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.BOOL:
          self.deleteCell = iprot.readBool();
        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('ColumnUpdate')
    if self.colFamily is not None:
      oprot.writeFieldBegin('colFamily', TType.STRING, 1)
      oprot.writeString(self.colFamily)
      oprot.writeFieldEnd()
    if self.colQualifier is not None:
      oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
      oprot.writeString(self.colQualifier)
      oprot.writeFieldEnd()
    if self.colVisibility is not None:
      oprot.writeFieldBegin('colVisibility', TType.STRING, 3)
      oprot.writeString(self.colVisibility)
      oprot.writeFieldEnd()
    if self.timestamp is not None:
      oprot.writeFieldBegin('timestamp', TType.I64, 4)
      oprot.writeI64(self.timestamp)
      oprot.writeFieldEnd()
    if self.value is not None:
      oprot.writeFieldBegin('value', TType.STRING, 5)
      oprot.writeString(self.value)
      oprot.writeFieldEnd()
    if self.deleteCell is not None:
      oprot.writeFieldBegin('deleteCell', TType.BOOL, 6)
      oprot.writeBool(self.deleteCell)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 DiskUsage:
  """
  Attributes:
   - tables
   - usage
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'tables', (TType.STRING,None), None, ), # 1
    (2, TType.I64, 'usage', None, None, ), # 2
  )

  def __init__(self, tables=None, usage=None,):
    self.tables = tables
    self.usage = usage

  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.tables = []
          (_etype3, _size0) = iprot.readListBegin()
          for _i4 in xrange(_size0):
            _elem5 = iprot.readString();
            self.tables.append(_elem5)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.usage = iprot.readI64();
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('DiskUsage')
    if self.tables is not None:
      oprot.writeFieldBegin('tables', TType.LIST, 1)
      oprot.writeListBegin(TType.STRING, len(self.tables))
      for iter6 in self.tables:
        oprot.writeString(iter6)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.usage is not None:
      oprot.writeFieldBegin('usage', TType.I64, 2)
      oprot.writeI64(self.usage)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 KeyValue:
  """
  Attributes:
   - key
   - value
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'key', (Key, Key.thrift_spec), None, ), # 1
    (2, TType.STRING, 'value', None, None, ), # 2
  )

  def __init__(self, key=None, value=None,):
    self.key = key
    self.value = value

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

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

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ScanResult:
  """
  Attributes:
   - results
   - more
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'results', (TType.STRUCT,(KeyValue, KeyValue.thrift_spec)), None, ), # 1
    (2, TType.BOOL, 'more', None, None, ), # 2
  )

  def __init__(self, results=None, more=None,):
    self.results = results
    self.more = more

  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.results = []
          (_etype10, _size7) = iprot.readListBegin()
          for _i11 in xrange(_size7):
            _elem12 = KeyValue()
            _elem12.read(iprot)
            self.results.append(_elem12)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.BOOL:
          self.more = iprot.readBool();
        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('ScanResult')
    if self.results is not None:
      oprot.writeFieldBegin('results', TType.LIST, 1)
      oprot.writeListBegin(TType.STRUCT, len(self.results))
      for iter13 in self.results:
        iter13.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.more is not None:
      oprot.writeFieldBegin('more', TType.BOOL, 2)
      oprot.writeBool(self.more)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 Range:
  """
  Attributes:
   - start
   - startInclusive
   - stop
   - stopInclusive
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'start', (Key, Key.thrift_spec), None, ), # 1
    (2, TType.BOOL, 'startInclusive', None, None, ), # 2
    (3, TType.STRUCT, 'stop', (Key, Key.thrift_spec), None, ), # 3
    (4, TType.BOOL, 'stopInclusive', None, None, ), # 4
  )

  def __init__(self, start=None, startInclusive=None, stop=None, stopInclusive=None,):
    self.start = start
    self.startInclusive = startInclusive
    self.stop = stop
    self.stopInclusive = stopInclusive

  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.start = Key()
          self.start.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.BOOL:
          self.startInclusive = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.stop = Key()
          self.stop.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.BOOL:
          self.stopInclusive = iprot.readBool();
        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('Range')
    if self.start is not None:
      oprot.writeFieldBegin('start', TType.STRUCT, 1)
      self.start.write(oprot)
      oprot.writeFieldEnd()
    if self.startInclusive is not None:
      oprot.writeFieldBegin('startInclusive', TType.BOOL, 2)
      oprot.writeBool(self.startInclusive)
      oprot.writeFieldEnd()
    if self.stop is not None:
      oprot.writeFieldBegin('stop', TType.STRUCT, 3)
      self.stop.write(oprot)
      oprot.writeFieldEnd()
    if self.stopInclusive is not None:
      oprot.writeFieldBegin('stopInclusive', TType.BOOL, 4)
      oprot.writeBool(self.stopInclusive)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ScanColumn:
  """
  Attributes:
   - colFamily
   - colQualifier
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'colFamily', None, None, ), # 1
    (2, TType.STRING, 'colQualifier', None, None, ), # 2
  )

  def __init__(self, colFamily=None, colQualifier=None,):
    self.colFamily = colFamily
    self.colQualifier = colQualifier

  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.colFamily = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.colQualifier = 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('ScanColumn')
    if self.colFamily is not None:
      oprot.writeFieldBegin('colFamily', TType.STRING, 1)
      oprot.writeString(self.colFamily)
      oprot.writeFieldEnd()
    if self.colQualifier is not None:
      oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
      oprot.writeString(self.colQualifier)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 IteratorSetting:
  """
  Attributes:
   - priority
   - name
   - iteratorClass
   - properties
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'priority', None, None, ), # 1
    (2, TType.STRING, 'name', None, None, ), # 2
    (3, TType.STRING, 'iteratorClass', None, None, ), # 3
    (4, TType.MAP, 'properties', (TType.STRING,None,TType.STRING,None), None, ), # 4
  )

  def __init__(self, priority=None, name=None, iteratorClass=None, properties=None,):
    self.priority = priority
    self.name = name
    self.iteratorClass = iteratorClass
    self.properties = properties

  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.priority = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.name = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.iteratorClass = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.MAP:
          self.properties = {}
          (_ktype15, _vtype16, _size14 ) = iprot.readMapBegin()
          for _i18 in xrange(_size14):
            _key19 = iprot.readString();
            _val20 = iprot.readString();
            self.properties[_key19] = _val20
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('IteratorSetting')
    if self.priority is not None:
      oprot.writeFieldBegin('priority', TType.I32, 1)
      oprot.writeI32(self.priority)
      oprot.writeFieldEnd()
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 2)
      oprot.writeString(self.name)
      oprot.writeFieldEnd()
    if self.iteratorClass is not None:
      oprot.writeFieldBegin('iteratorClass', TType.STRING, 3)
      oprot.writeString(self.iteratorClass)
      oprot.writeFieldEnd()
    if self.properties is not None:
      oprot.writeFieldBegin('properties', TType.MAP, 4)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.properties))
      for kiter21,viter22 in self.properties.items():
        oprot.writeString(kiter21)
        oprot.writeString(viter22)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ScanOptions:
  """
  Attributes:
   - authorizations
   - range
   - columns
   - iterators
   - bufferSize
  """

  thrift_spec = (
    None, # 0
    (1, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 1
    (2, TType.STRUCT, 'range', (Range, Range.thrift_spec), None, ), # 2
    (3, TType.LIST, 'columns', (TType.STRUCT,(ScanColumn, ScanColumn.thrift_spec)), None, ), # 3
    (4, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 4
    (5, TType.I32, 'bufferSize', None, None, ), # 5
  )

  def __init__(self, authorizations=None, range=None, columns=None, iterators=None, bufferSize=None,):
    self.authorizations = authorizations
    self.range = range
    self.columns = columns
    self.iterators = iterators
    self.bufferSize = bufferSize

  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.SET:
          self.authorizations = set()
          (_etype26, _size23) = iprot.readSetBegin()
          for _i27 in xrange(_size23):
            _elem28 = iprot.readString();
            self.authorizations.add(_elem28)
          iprot.readSetEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.range = Range()
          self.range.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.columns = []
          (_etype32, _size29) = iprot.readListBegin()
          for _i33 in xrange(_size29):
            _elem34 = ScanColumn()
            _elem34.read(iprot)
            self.columns.append(_elem34)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.LIST:
          self.iterators = []
          (_etype38, _size35) = iprot.readListBegin()
          for _i39 in xrange(_size35):
            _elem40 = IteratorSetting()
            _elem40.read(iprot)
            self.iterators.append(_elem40)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.bufferSize = 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('ScanOptions')
    if self.authorizations is not None:
      oprot.writeFieldBegin('authorizations', TType.SET, 1)
      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
      for iter41 in self.authorizations:
        oprot.writeString(iter41)
      oprot.writeSetEnd()
      oprot.writeFieldEnd()
    if self.range is not None:
      oprot.writeFieldBegin('range', TType.STRUCT, 2)
      self.range.write(oprot)
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 3)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter42 in self.columns:
        iter42.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.iterators is not None:
      oprot.writeFieldBegin('iterators', TType.LIST, 4)
      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
      for iter43 in self.iterators:
        iter43.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.bufferSize is not None:
      oprot.writeFieldBegin('bufferSize', TType.I32, 5)
      oprot.writeI32(self.bufferSize)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 BatchScanOptions:
  """
  Attributes:
   - authorizations
   - ranges
   - columns
   - iterators
   - threads
  """

  thrift_spec = (
    None, # 0
    (1, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 1
    (2, TType.LIST, 'ranges', (TType.STRUCT,(Range, Range.thrift_spec)), None, ), # 2
    (3, TType.LIST, 'columns', (TType.STRUCT,(ScanColumn, ScanColumn.thrift_spec)), None, ), # 3
    (4, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 4
    (5, TType.I32, 'threads', None, None, ), # 5
  )

  def __init__(self, authorizations=None, ranges=None, columns=None, iterators=None, threads=None,):
    self.authorizations = authorizations
    self.ranges = ranges
    self.columns = columns
    self.iterators = iterators
    self.threads = threads

  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.SET:
          self.authorizations = set()
          (_etype47, _size44) = iprot.readSetBegin()
          for _i48 in xrange(_size44):
            _elem49 = iprot.readString();
            self.authorizations.add(_elem49)
          iprot.readSetEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.ranges = []
          (_etype53, _size50) = iprot.readListBegin()
          for _i54 in xrange(_size50):
            _elem55 = Range()
            _elem55.read(iprot)
            self.ranges.append(_elem55)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.columns = []
          (_etype59, _size56) = iprot.readListBegin()
          for _i60 in xrange(_size56):
            _elem61 = ScanColumn()
            _elem61.read(iprot)
            self.columns.append(_elem61)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.LIST:
          self.iterators = []
          (_etype65, _size62) = iprot.readListBegin()
          for _i66 in xrange(_size62):
            _elem67 = IteratorSetting()
            _elem67.read(iprot)
            self.iterators.append(_elem67)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.threads = 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('BatchScanOptions')
    if self.authorizations is not None:
      oprot.writeFieldBegin('authorizations', TType.SET, 1)
      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
      for iter68 in self.authorizations:
        oprot.writeString(iter68)
      oprot.writeSetEnd()
      oprot.writeFieldEnd()
    if self.ranges is not None:
      oprot.writeFieldBegin('ranges', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.ranges))
      for iter69 in self.ranges:
        iter69.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 3)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter70 in self.columns:
        iter70.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.iterators is not None:
      oprot.writeFieldBegin('iterators', TType.LIST, 4)
      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
      for iter71 in self.iterators:
        iter71.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.threads is not None:
      oprot.writeFieldBegin('threads', TType.I32, 5)
      oprot.writeI32(self.threads)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 KeyValueAndPeek:
  """
  Attributes:
   - keyValue
   - hasNext
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'keyValue', (KeyValue, KeyValue.thrift_spec), None, ), # 1
    (2, TType.BOOL, 'hasNext', None, None, ), # 2
  )

  def __init__(self, keyValue=None, hasNext=None,):
    self.keyValue = keyValue
    self.hasNext = hasNext

  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.keyValue = KeyValue()
          self.keyValue.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.BOOL:
          self.hasNext = iprot.readBool();
        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('KeyValueAndPeek')
    if self.keyValue is not None:
      oprot.writeFieldBegin('keyValue', TType.STRUCT, 1)
      self.keyValue.write(oprot)
      oprot.writeFieldEnd()
    if self.hasNext is not None:
      oprot.writeFieldBegin('hasNext', TType.BOOL, 2)
      oprot.writeBool(self.hasNext)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 KeyExtent:
  """
  Attributes:
   - tableId
   - endRow
   - prevEndRow
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'tableId', None, None, ), # 1
    (2, TType.STRING, 'endRow', None, None, ), # 2
    (3, TType.STRING, 'prevEndRow', None, None, ), # 3
  )

  def __init__(self, tableId=None, endRow=None, prevEndRow=None,):
    self.tableId = tableId
    self.endRow = endRow
    self.prevEndRow = prevEndRow

  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.tableId = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.endRow = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.prevEndRow = 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('KeyExtent')
    if self.tableId is not None:
      oprot.writeFieldBegin('tableId', TType.STRING, 1)
      oprot.writeString(self.tableId)
      oprot.writeFieldEnd()
    if self.endRow is not None:
      oprot.writeFieldBegin('endRow', TType.STRING, 2)
      oprot.writeString(self.endRow)
      oprot.writeFieldEnd()
    if self.prevEndRow is not None:
      oprot.writeFieldBegin('prevEndRow', TType.STRING, 3)
      oprot.writeString(self.prevEndRow)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 Column:
  """
  Attributes:
   - colFamily
   - colQualifier
   - colVisibility
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'colFamily', None, None, ), # 1
    (2, TType.STRING, 'colQualifier', None, None, ), # 2
    (3, TType.STRING, 'colVisibility', None, None, ), # 3
  )

  def __init__(self, colFamily=None, colQualifier=None, colVisibility=None,):
    self.colFamily = colFamily
    self.colQualifier = colQualifier
    self.colVisibility = colVisibility

  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.colFamily = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.colQualifier = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.colVisibility = 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('Column')
    if self.colFamily is not None:
      oprot.writeFieldBegin('colFamily', TType.STRING, 1)
      oprot.writeString(self.colFamily)
      oprot.writeFieldEnd()
    if self.colQualifier is not None:
      oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
      oprot.writeString(self.colQualifier)
      oprot.writeFieldEnd()
    if self.colVisibility is not None:
      oprot.writeFieldBegin('colVisibility', TType.STRING, 3)
      oprot.writeString(self.colVisibility)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 Condition:
  """
  Attributes:
   - column
   - timestamp
   - value
   - iterators
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'column', (Column, Column.thrift_spec), None, ), # 1
    (2, TType.I64, 'timestamp', None, None, ), # 2
    (3, TType.STRING, 'value', None, None, ), # 3
    (4, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 4
  )

  def __init__(self, column=None, timestamp=None, value=None, iterators=None,):
    self.column = column
    self.timestamp = timestamp
    self.value = value
    self.iterators = iterators

  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 = Column()
          self.column.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.timestamp = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.value = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.LIST:
          self.iterators = []
          (_etype75, _size72) = iprot.readListBegin()
          for _i76 in xrange(_size72):
            _elem77 = IteratorSetting()
            _elem77.read(iprot)
            self.iterators.append(_elem77)
          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('Condition')
    if self.column is not None:
      oprot.writeFieldBegin('column', TType.STRUCT, 1)
      self.column.write(oprot)
      oprot.writeFieldEnd()
    if self.timestamp is not None:
      oprot.writeFieldBegin('timestamp', TType.I64, 2)
      oprot.writeI64(self.timestamp)
      oprot.writeFieldEnd()
    if self.value is not None:
      oprot.writeFieldBegin('value', TType.STRING, 3)
      oprot.writeString(self.value)
      oprot.writeFieldEnd()
    if self.iterators is not None:
      oprot.writeFieldBegin('iterators', TType.LIST, 4)
      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
      for iter78 in self.iterators:
        iter78.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ConditionalUpdates:
  """
  Attributes:
   - conditions
   - updates
  """

  thrift_spec = (
    None, # 0
    None, # 1
    (2, TType.LIST, 'conditions', (TType.STRUCT,(Condition, Condition.thrift_spec)), None, ), # 2
    (3, TType.LIST, 'updates', (TType.STRUCT,(ColumnUpdate, ColumnUpdate.thrift_spec)), None, ), # 3
  )

  def __init__(self, conditions=None, updates=None,):
    self.conditions = conditions
    self.updates = updates

  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 == 2:
        if ftype == TType.LIST:
          self.conditions = []
          (_etype82, _size79) = iprot.readListBegin()
          for _i83 in xrange(_size79):
            _elem84 = Condition()
            _elem84.read(iprot)
            self.conditions.append(_elem84)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.updates = []
          (_etype88, _size85) = iprot.readListBegin()
          for _i89 in xrange(_size85):
            _elem90 = ColumnUpdate()
            _elem90.read(iprot)
            self.updates.append(_elem90)
          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('ConditionalUpdates')
    if self.conditions is not None:
      oprot.writeFieldBegin('conditions', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.conditions))
      for iter91 in self.conditions:
        iter91.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.updates is not None:
      oprot.writeFieldBegin('updates', TType.LIST, 3)
      oprot.writeListBegin(TType.STRUCT, len(self.updates))
      for iter92 in self.updates:
        iter92.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ConditionalWriterOptions:
  """
  Attributes:
   - maxMemory
   - timeoutMs
   - threads
   - authorizations
   - durability
  """

  thrift_spec = (
    None, # 0
    (1, TType.I64, 'maxMemory', None, None, ), # 1
    (2, TType.I64, 'timeoutMs', None, None, ), # 2
    (3, TType.I32, 'threads', None, None, ), # 3
    (4, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 4
    (5, TType.I32, 'durability', None, None, ), # 5
  )

  def __init__(self, maxMemory=None, timeoutMs=None, threads=None, authorizations=None, durability=None,):
    self.maxMemory = maxMemory
    self.timeoutMs = timeoutMs
    self.threads = threads
    self.authorizations = authorizations
    self.durability = durability

  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.I64:
          self.maxMemory = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.timeoutMs = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.threads = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.SET:
          self.authorizations = set()
          (_etype96, _size93) = iprot.readSetBegin()
          for _i97 in xrange(_size93):
            _elem98 = iprot.readString();
            self.authorizations.add(_elem98)
          iprot.readSetEnd()
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.durability = 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('ConditionalWriterOptions')
    if self.maxMemory is not None:
      oprot.writeFieldBegin('maxMemory', TType.I64, 1)
      oprot.writeI64(self.maxMemory)
      oprot.writeFieldEnd()
    if self.timeoutMs is not None:
      oprot.writeFieldBegin('timeoutMs', TType.I64, 2)
      oprot.writeI64(self.timeoutMs)
      oprot.writeFieldEnd()
    if self.threads is not None:
      oprot.writeFieldBegin('threads', TType.I32, 3)
      oprot.writeI32(self.threads)
      oprot.writeFieldEnd()
    if self.authorizations is not None:
      oprot.writeFieldBegin('authorizations', TType.SET, 4)
      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
      for iter99 in self.authorizations:
        oprot.writeString(iter99)
      oprot.writeSetEnd()
      oprot.writeFieldEnd()
    if self.durability is not None:
      oprot.writeFieldBegin('durability', TType.I32, 5)
      oprot.writeI32(self.durability)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ActiveScan:
  """
  Attributes:
   - client
   - user
   - table
   - age
   - idleTime
   - type
   - state
   - extent
   - columns
   - iterators
   - authorizations
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'client', None, None, ), # 1
    (2, TType.STRING, 'user', None, None, ), # 2
    (3, TType.STRING, 'table', None, None, ), # 3
    (4, TType.I64, 'age', None, None, ), # 4
    (5, TType.I64, 'idleTime', None, None, ), # 5
    (6, TType.I32, 'type', None, None, ), # 6
    (7, TType.I32, 'state', None, None, ), # 7
    (8, TType.STRUCT, 'extent', (KeyExtent, KeyExtent.thrift_spec), None, ), # 8
    (9, TType.LIST, 'columns', (TType.STRUCT,(Column, Column.thrift_spec)), None, ), # 9
    (10, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 10
    (11, TType.LIST, 'authorizations', (TType.STRING,None), None, ), # 11
  )

  def __init__(self, client=None, user=None, table=None, age=None, idleTime=None, type=None, state=None, extent=None, columns=None, iterators=None, authorizations=None,):
    self.client = client
    self.user = user
    self.table = table
    self.age = age
    self.idleTime = idleTime
    self.type = type
    self.state = state
    self.extent = extent
    self.columns = columns
    self.iterators = iterators
    self.authorizations = authorizations

  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.client = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.user = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.table = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I64:
          self.age = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I64:
          self.idleTime = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.I32:
          self.type = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 7:
        if ftype == TType.I32:
          self.state = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 8:
        if ftype == TType.STRUCT:
          self.extent = KeyExtent()
          self.extent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 9:
        if ftype == TType.LIST:
          self.columns = []
          (_etype103, _size100) = iprot.readListBegin()
          for _i104 in xrange(_size100):
            _elem105 = Column()
            _elem105.read(iprot)
            self.columns.append(_elem105)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 10:
        if ftype == TType.LIST:
          self.iterators = []
          (_etype109, _size106) = iprot.readListBegin()
          for _i110 in xrange(_size106):
            _elem111 = IteratorSetting()
            _elem111.read(iprot)
            self.iterators.append(_elem111)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 11:
        if ftype == TType.LIST:
          self.authorizations = []
          (_etype115, _size112) = iprot.readListBegin()
          for _i116 in xrange(_size112):
            _elem117 = iprot.readString();
            self.authorizations.append(_elem117)
          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('ActiveScan')
    if self.client is not None:
      oprot.writeFieldBegin('client', TType.STRING, 1)
      oprot.writeString(self.client)
      oprot.writeFieldEnd()
    if self.user is not None:
      oprot.writeFieldBegin('user', TType.STRING, 2)
      oprot.writeString(self.user)
      oprot.writeFieldEnd()
    if self.table is not None:
      oprot.writeFieldBegin('table', TType.STRING, 3)
      oprot.writeString(self.table)
      oprot.writeFieldEnd()
    if self.age is not None:
      oprot.writeFieldBegin('age', TType.I64, 4)
      oprot.writeI64(self.age)
      oprot.writeFieldEnd()
    if self.idleTime is not None:
      oprot.writeFieldBegin('idleTime', TType.I64, 5)
      oprot.writeI64(self.idleTime)
      oprot.writeFieldEnd()
    if self.type is not None:
      oprot.writeFieldBegin('type', TType.I32, 6)
      oprot.writeI32(self.type)
      oprot.writeFieldEnd()
    if self.state is not None:
      oprot.writeFieldBegin('state', TType.I32, 7)
      oprot.writeI32(self.state)
      oprot.writeFieldEnd()
    if self.extent is not None:
      oprot.writeFieldBegin('extent', TType.STRUCT, 8)
      self.extent.write(oprot)
      oprot.writeFieldEnd()
    if self.columns is not None:
      oprot.writeFieldBegin('columns', TType.LIST, 9)
      oprot.writeListBegin(TType.STRUCT, len(self.columns))
      for iter118 in self.columns:
        iter118.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.iterators is not None:
      oprot.writeFieldBegin('iterators', TType.LIST, 10)
      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
      for iter119 in self.iterators:
        iter119.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.authorizations is not None:
      oprot.writeFieldBegin('authorizations', TType.LIST, 11)
      oprot.writeListBegin(TType.STRING, len(self.authorizations))
      for iter120 in self.authorizations:
        oprot.writeString(iter120)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 ActiveCompaction:
  """
  Attributes:
   - extent
   - age
   - inputFiles
   - outputFile
   - type
   - reason
   - localityGroup
   - entriesRead
   - entriesWritten
   - iterators
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'extent', (KeyExtent, KeyExtent.thrift_spec), None, ), # 1
    (2, TType.I64, 'age', None, None, ), # 2
    (3, TType.LIST, 'inputFiles', (TType.STRING,None), None, ), # 3
    (4, TType.STRING, 'outputFile', None, None, ), # 4
    (5, TType.I32, 'type', None, None, ), # 5
    (6, TType.I32, 'reason', None, None, ), # 6
    (7, TType.STRING, 'localityGroup', None, None, ), # 7
    (8, TType.I64, 'entriesRead', None, None, ), # 8
    (9, TType.I64, 'entriesWritten', None, None, ), # 9
    (10, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 10
  )

  def __init__(self, extent=None, age=None, inputFiles=None, outputFile=None, type=None, reason=None, localityGroup=None, entriesRead=None, entriesWritten=None, iterators=None,):
    self.extent = extent
    self.age = age
    self.inputFiles = inputFiles
    self.outputFile = outputFile
    self.type = type
    self.reason = reason
    self.localityGroup = localityGroup
    self.entriesRead = entriesRead
    self.entriesWritten = entriesWritten
    self.iterators = iterators

  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.extent = KeyExtent()
          self.extent.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.age = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.inputFiles = []
          (_etype124, _size121) = iprot.readListBegin()
          for _i125 in xrange(_size121):
            _elem126 = iprot.readString();
            self.inputFiles.append(_elem126)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.outputFile = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.type = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.I32:
          self.reason = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 7:
        if ftype == TType.STRING:
          self.localityGroup = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 8:
        if ftype == TType.I64:
          self.entriesRead = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 9:
        if ftype == TType.I64:
          self.entriesWritten = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 10:
        if ftype == TType.LIST:
          self.iterators = []
          (_etype130, _size127) = iprot.readListBegin()
          for _i131 in xrange(_size127):
            _elem132 = IteratorSetting()
            _elem132.read(iprot)
            self.iterators.append(_elem132)
          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('ActiveCompaction')
    if self.extent is not None:
      oprot.writeFieldBegin('extent', TType.STRUCT, 1)
      self.extent.write(oprot)
      oprot.writeFieldEnd()
    if self.age is not None:
      oprot.writeFieldBegin('age', TType.I64, 2)
      oprot.writeI64(self.age)
      oprot.writeFieldEnd()
    if self.inputFiles is not None:
      oprot.writeFieldBegin('inputFiles', TType.LIST, 3)
      oprot.writeListBegin(TType.STRING, len(self.inputFiles))
      for iter133 in self.inputFiles:
        oprot.writeString(iter133)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.outputFile is not None:
      oprot.writeFieldBegin('outputFile', TType.STRING, 4)
      oprot.writeString(self.outputFile)
      oprot.writeFieldEnd()
    if self.type is not None:
      oprot.writeFieldBegin('type', TType.I32, 5)
      oprot.writeI32(self.type)
      oprot.writeFieldEnd()
    if self.reason is not None:
      oprot.writeFieldBegin('reason', TType.I32, 6)
      oprot.writeI32(self.reason)
      oprot.writeFieldEnd()
    if self.localityGroup is not None:
      oprot.writeFieldBegin('localityGroup', TType.STRING, 7)
      oprot.writeString(self.localityGroup)
      oprot.writeFieldEnd()
    if self.entriesRead is not None:
      oprot.writeFieldBegin('entriesRead', TType.I64, 8)
      oprot.writeI64(self.entriesRead)
      oprot.writeFieldEnd()
    if self.entriesWritten is not None:
      oprot.writeFieldBegin('entriesWritten', TType.I64, 9)
      oprot.writeI64(self.entriesWritten)
      oprot.writeFieldEnd()
    if self.iterators is not None:
      oprot.writeFieldBegin('iterators', TType.LIST, 10)
      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
      for iter134 in self.iterators:
        iter134.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 WriterOptions:
  """
  Attributes:
   - maxMemory
   - latencyMs
   - timeoutMs
   - threads
   - durability
  """

  thrift_spec = (
    None, # 0
    (1, TType.I64, 'maxMemory', None, None, ), # 1
    (2, TType.I64, 'latencyMs', None, None, ), # 2
    (3, TType.I64, 'timeoutMs', None, None, ), # 3
    (4, TType.I32, 'threads', None, None, ), # 4
    (5, TType.I32, 'durability', None, None, ), # 5
  )

  def __init__(self, maxMemory=None, latencyMs=None, timeoutMs=None, threads=None, durability=None,):
    self.maxMemory = maxMemory
    self.latencyMs = latencyMs
    self.timeoutMs = timeoutMs
    self.threads = threads
    self.durability = durability

  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.I64:
          self.maxMemory = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.latencyMs = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I64:
          self.timeoutMs = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.threads = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.durability = 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('WriterOptions')
    if self.maxMemory is not None:
      oprot.writeFieldBegin('maxMemory', TType.I64, 1)
      oprot.writeI64(self.maxMemory)
      oprot.writeFieldEnd()
    if self.latencyMs is not None:
      oprot.writeFieldBegin('latencyMs', TType.I64, 2)
      oprot.writeI64(self.latencyMs)
      oprot.writeFieldEnd()
    if self.timeoutMs is not None:
      oprot.writeFieldBegin('timeoutMs', TType.I64, 3)
      oprot.writeI64(self.timeoutMs)
      oprot.writeFieldEnd()
    if self.threads is not None:
      oprot.writeFieldBegin('threads', TType.I32, 4)
      oprot.writeI32(self.threads)
      oprot.writeFieldEnd()
    if self.durability is not None:
      oprot.writeFieldBegin('durability', TType.I32, 5)
      oprot.writeI32(self.durability)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 CompactionStrategyConfig:
  """
  Attributes:
   - className
   - options
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'className', None, None, ), # 1
    (2, TType.MAP, 'options', (TType.STRING,None,TType.STRING,None), None, ), # 2
  )

  def __init__(self, className=None, options=None,):
    self.className = className
    self.options = options

  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.className = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.MAP:
          self.options = {}
          (_ktype136, _vtype137, _size135 ) = iprot.readMapBegin()
          for _i139 in xrange(_size135):
            _key140 = iprot.readString();
            _val141 = iprot.readString();
            self.options[_key140] = _val141
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('CompactionStrategyConfig')
    if self.className is not None:
      oprot.writeFieldBegin('className', TType.STRING, 1)
      oprot.writeString(self.className)
      oprot.writeFieldEnd()
    if self.options is not None:
      oprot.writeFieldBegin('options', TType.MAP, 2)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.options))
      for kiter142,viter143 in self.options.items():
        oprot.writeString(kiter142)
        oprot.writeString(viter143)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 UnknownScanner(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('UnknownScanner')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 UnknownWriter(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('UnknownWriter')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 NoMoreEntriesException(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('NoMoreEntriesException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 AccumuloException(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('AccumuloException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 AccumuloSecurityException(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('AccumuloSecurityException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 TableNotFoundException(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('TableNotFoundException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 TableExistsException(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('TableExistsException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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 MutationsRejectedException(TException):
  """
  Attributes:
   - msg
  """

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

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

  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.msg = 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('MutationsRejectedException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __str__(self):
    return repr(self)

  def __repr__(self):
    L = ['%s=%r' % (key, value)
      for key, value in self.__dict__.iteritems()]
    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)
