/*
 * 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.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
#ifndef proxy_TYPES_H
#define proxy_TYPES_H

#include <iosfwd>

#include <thrift/Thrift.h>
#include <thrift/TApplicationException.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/transport/TTransport.h>

#include <thrift/cxxfunctional.h>


namespace accumulo {

struct PartialKey {
  enum type {
    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
  };
};

extern const std::map<int, const char*> _PartialKey_VALUES_TO_NAMES;

struct TablePermission {
  enum type {
    READ = 2,
    WRITE = 3,
    BULK_IMPORT = 4,
    ALTER_TABLE = 5,
    GRANT = 6,
    DROP_TABLE = 7
  };
};

extern const std::map<int, const char*> _TablePermission_VALUES_TO_NAMES;

struct SystemPermission {
  enum type {
    GRANT = 0,
    CREATE_TABLE = 1,
    DROP_TABLE = 2,
    ALTER_TABLE = 3,
    CREATE_USER = 4,
    DROP_USER = 5,
    ALTER_USER = 6,
    SYSTEM = 7
  };
};

extern const std::map<int, const char*> _SystemPermission_VALUES_TO_NAMES;

struct NamespacePermission {
  enum type {
    READ = 0,
    WRITE = 1,
    ALTER_NAMESPACE = 2,
    GRANT = 3,
    ALTER_TABLE = 4,
    CREATE_TABLE = 5,
    DROP_TABLE = 6,
    BULK_IMPORT = 7,
    DROP_NAMESPACE = 8
  };
};

extern const std::map<int, const char*> _NamespacePermission_VALUES_TO_NAMES;

struct ScanType {
  enum type {
    SINGLE = 0,
    BATCH = 1
  };
};

extern const std::map<int, const char*> _ScanType_VALUES_TO_NAMES;

struct ScanState {
  enum type {
    IDLE = 0,
    RUNNING = 1,
    QUEUED = 2
  };
};

extern const std::map<int, const char*> _ScanState_VALUES_TO_NAMES;

struct ConditionalStatus {
  enum type {
    ACCEPTED = 0,
    REJECTED = 1,
    VIOLATED = 2,
    UNKNOWN = 3,
    INVISIBLE_VISIBILITY = 4
  };
};

extern const std::map<int, const char*> _ConditionalStatus_VALUES_TO_NAMES;

struct Durability {
  enum type {
    DEFAULT = 0,
    NONE = 1,
    LOG = 2,
    FLUSH = 3,
    SYNC = 4
  };
};

extern const std::map<int, const char*> _Durability_VALUES_TO_NAMES;

struct CompactionType {
  enum type {
    MINOR = 0,
    MERGE = 1,
    MAJOR = 2,
    FULL = 3
  };
};

extern const std::map<int, const char*> _CompactionType_VALUES_TO_NAMES;

struct CompactionReason {
  enum type {
    USER = 0,
    SYSTEM = 1,
    CHOP = 2,
    IDLE = 3,
    CLOSE = 4
  };
};

extern const std::map<int, const char*> _CompactionReason_VALUES_TO_NAMES;

struct IteratorScope {
  enum type {
    MINC = 0,
    MAJC = 1,
    SCAN = 2
  };
};

extern const std::map<int, const char*> _IteratorScope_VALUES_TO_NAMES;

struct TimeType {
  enum type {
    LOGICAL = 0,
    MILLIS = 1
  };
};

extern const std::map<int, const char*> _TimeType_VALUES_TO_NAMES;

class Key;

class ColumnUpdate;

class DiskUsage;

class KeyValue;

class ScanResult;

class Range;

class ScanColumn;

class IteratorSetting;

class ScanOptions;

class BatchScanOptions;

class KeyValueAndPeek;

class KeyExtent;

class Column;

class Condition;

class ConditionalUpdates;

class ConditionalWriterOptions;

class ActiveScan;

class ActiveCompaction;

class WriterOptions;

class CompactionStrategyConfig;

class UnknownScanner;

class UnknownWriter;

class NoMoreEntriesException;

class AccumuloException;

class AccumuloSecurityException;

class TableNotFoundException;

class TableExistsException;

class MutationsRejectedException;

class NamespaceExistsException;

class NamespaceNotFoundException;

class NamespaceNotEmptyException;

typedef struct _Key__isset {
  _Key__isset() : row(false), colFamily(false), colQualifier(false), colVisibility(false), timestamp(true) {}
  bool row :1;
  bool colFamily :1;
  bool colQualifier :1;
  bool colVisibility :1;
  bool timestamp :1;
} _Key__isset;

class Key {
 public:

  Key(const Key&);
  Key& operator=(const Key&);
  Key() : row(), colFamily(), colQualifier(), colVisibility(), timestamp(9223372036854775807LL) {
  }

  virtual ~Key() throw();
  std::string row;
  std::string colFamily;
  std::string colQualifier;
  std::string colVisibility;
  int64_t timestamp;

  _Key__isset __isset;

  void __set_row(const std::string& val);

  void __set_colFamily(const std::string& val);

  void __set_colQualifier(const std::string& val);

  void __set_colVisibility(const std::string& val);

  void __set_timestamp(const int64_t val);

  bool operator == (const Key & rhs) const
  {
    if (!(row == rhs.row))
      return false;
    if (!(colFamily == rhs.colFamily))
      return false;
    if (!(colQualifier == rhs.colQualifier))
      return false;
    if (!(colVisibility == rhs.colVisibility))
      return false;
    if (__isset.timestamp != rhs.__isset.timestamp)
      return false;
    else if (__isset.timestamp && !(timestamp == rhs.timestamp))
      return false;
    return true;
  }
  bool operator != (const Key &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Key & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Key &a, Key &b);

inline std::ostream& operator<<(std::ostream& out, const Key& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ColumnUpdate__isset {
  _ColumnUpdate__isset() : colFamily(false), colQualifier(false), colVisibility(false), timestamp(false), value(false), deleteCell(false) {}
  bool colFamily :1;
  bool colQualifier :1;
  bool colVisibility :1;
  bool timestamp :1;
  bool value :1;
  bool deleteCell :1;
} _ColumnUpdate__isset;

class ColumnUpdate {
 public:

  ColumnUpdate(const ColumnUpdate&);
  ColumnUpdate& operator=(const ColumnUpdate&);
  ColumnUpdate() : colFamily(), colQualifier(), colVisibility(), timestamp(0), value(), deleteCell(0) {
  }

  virtual ~ColumnUpdate() throw();
  std::string colFamily;
  std::string colQualifier;
  std::string colVisibility;
  int64_t timestamp;
  std::string value;
  bool deleteCell;

  _ColumnUpdate__isset __isset;

  void __set_colFamily(const std::string& val);

  void __set_colQualifier(const std::string& val);

  void __set_colVisibility(const std::string& val);

  void __set_timestamp(const int64_t val);

  void __set_value(const std::string& val);

  void __set_deleteCell(const bool val);

  bool operator == (const ColumnUpdate & rhs) const
  {
    if (!(colFamily == rhs.colFamily))
      return false;
    if (!(colQualifier == rhs.colQualifier))
      return false;
    if (__isset.colVisibility != rhs.__isset.colVisibility)
      return false;
    else if (__isset.colVisibility && !(colVisibility == rhs.colVisibility))
      return false;
    if (__isset.timestamp != rhs.__isset.timestamp)
      return false;
    else if (__isset.timestamp && !(timestamp == rhs.timestamp))
      return false;
    if (__isset.value != rhs.__isset.value)
      return false;
    else if (__isset.value && !(value == rhs.value))
      return false;
    if (__isset.deleteCell != rhs.__isset.deleteCell)
      return false;
    else if (__isset.deleteCell && !(deleteCell == rhs.deleteCell))
      return false;
    return true;
  }
  bool operator != (const ColumnUpdate &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ColumnUpdate & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ColumnUpdate &a, ColumnUpdate &b);

inline std::ostream& operator<<(std::ostream& out, const ColumnUpdate& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _DiskUsage__isset {
  _DiskUsage__isset() : tables(false), usage(false) {}
  bool tables :1;
  bool usage :1;
} _DiskUsage__isset;

class DiskUsage {
 public:

  DiskUsage(const DiskUsage&);
  DiskUsage& operator=(const DiskUsage&);
  DiskUsage() : usage(0) {
  }

  virtual ~DiskUsage() throw();
  std::vector<std::string>  tables;
  int64_t usage;

  _DiskUsage__isset __isset;

  void __set_tables(const std::vector<std::string> & val);

  void __set_usage(const int64_t val);

  bool operator == (const DiskUsage & rhs) const
  {
    if (!(tables == rhs.tables))
      return false;
    if (!(usage == rhs.usage))
      return false;
    return true;
  }
  bool operator != (const DiskUsage &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const DiskUsage & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(DiskUsage &a, DiskUsage &b);

inline std::ostream& operator<<(std::ostream& out, const DiskUsage& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _KeyValue__isset {
  _KeyValue__isset() : key(false), value(false) {}
  bool key :1;
  bool value :1;
} _KeyValue__isset;

class KeyValue {
 public:

  KeyValue(const KeyValue&);
  KeyValue& operator=(const KeyValue&);
  KeyValue() : value() {
  }

  virtual ~KeyValue() throw();
  Key key;
  std::string value;

  _KeyValue__isset __isset;

  void __set_key(const Key& val);

  void __set_value(const std::string& val);

  bool operator == (const KeyValue & rhs) const
  {
    if (!(key == rhs.key))
      return false;
    if (!(value == rhs.value))
      return false;
    return true;
  }
  bool operator != (const KeyValue &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const KeyValue & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(KeyValue &a, KeyValue &b);

inline std::ostream& operator<<(std::ostream& out, const KeyValue& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ScanResult__isset {
  _ScanResult__isset() : results(false), more(false) {}
  bool results :1;
  bool more :1;
} _ScanResult__isset;

class ScanResult {
 public:

  ScanResult(const ScanResult&);
  ScanResult& operator=(const ScanResult&);
  ScanResult() : more(0) {
  }

  virtual ~ScanResult() throw();
  std::vector<KeyValue>  results;
  bool more;

  _ScanResult__isset __isset;

  void __set_results(const std::vector<KeyValue> & val);

  void __set_more(const bool val);

  bool operator == (const ScanResult & rhs) const
  {
    if (!(results == rhs.results))
      return false;
    if (!(more == rhs.more))
      return false;
    return true;
  }
  bool operator != (const ScanResult &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ScanResult & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ScanResult &a, ScanResult &b);

inline std::ostream& operator<<(std::ostream& out, const ScanResult& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _Range__isset {
  _Range__isset() : start(false), startInclusive(false), stop(false), stopInclusive(false) {}
  bool start :1;
  bool startInclusive :1;
  bool stop :1;
  bool stopInclusive :1;
} _Range__isset;

class Range {
 public:

  Range(const Range&);
  Range& operator=(const Range&);
  Range() : startInclusive(0), stopInclusive(0) {
  }

  virtual ~Range() throw();
  Key start;
  bool startInclusive;
  Key stop;
  bool stopInclusive;

  _Range__isset __isset;

  void __set_start(const Key& val);

  void __set_startInclusive(const bool val);

  void __set_stop(const Key& val);

  void __set_stopInclusive(const bool val);

  bool operator == (const Range & rhs) const
  {
    if (!(start == rhs.start))
      return false;
    if (!(startInclusive == rhs.startInclusive))
      return false;
    if (!(stop == rhs.stop))
      return false;
    if (!(stopInclusive == rhs.stopInclusive))
      return false;
    return true;
  }
  bool operator != (const Range &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Range & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Range &a, Range &b);

inline std::ostream& operator<<(std::ostream& out, const Range& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ScanColumn__isset {
  _ScanColumn__isset() : colFamily(false), colQualifier(false) {}
  bool colFamily :1;
  bool colQualifier :1;
} _ScanColumn__isset;

class ScanColumn {
 public:

  ScanColumn(const ScanColumn&);
  ScanColumn& operator=(const ScanColumn&);
  ScanColumn() : colFamily(), colQualifier() {
  }

  virtual ~ScanColumn() throw();
  std::string colFamily;
  std::string colQualifier;

  _ScanColumn__isset __isset;

  void __set_colFamily(const std::string& val);

  void __set_colQualifier(const std::string& val);

  bool operator == (const ScanColumn & rhs) const
  {
    if (!(colFamily == rhs.colFamily))
      return false;
    if (__isset.colQualifier != rhs.__isset.colQualifier)
      return false;
    else if (__isset.colQualifier && !(colQualifier == rhs.colQualifier))
      return false;
    return true;
  }
  bool operator != (const ScanColumn &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ScanColumn & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ScanColumn &a, ScanColumn &b);

inline std::ostream& operator<<(std::ostream& out, const ScanColumn& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _IteratorSetting__isset {
  _IteratorSetting__isset() : priority(false), name(false), iteratorClass(false), properties(false) {}
  bool priority :1;
  bool name :1;
  bool iteratorClass :1;
  bool properties :1;
} _IteratorSetting__isset;

class IteratorSetting {
 public:

  IteratorSetting(const IteratorSetting&);
  IteratorSetting& operator=(const IteratorSetting&);
  IteratorSetting() : priority(0), name(), iteratorClass() {
  }

  virtual ~IteratorSetting() throw();
  int32_t priority;
  std::string name;
  std::string iteratorClass;
  std::map<std::string, std::string>  properties;

  _IteratorSetting__isset __isset;

  void __set_priority(const int32_t val);

  void __set_name(const std::string& val);

  void __set_iteratorClass(const std::string& val);

  void __set_properties(const std::map<std::string, std::string> & val);

  bool operator == (const IteratorSetting & rhs) const
  {
    if (!(priority == rhs.priority))
      return false;
    if (!(name == rhs.name))
      return false;
    if (!(iteratorClass == rhs.iteratorClass))
      return false;
    if (!(properties == rhs.properties))
      return false;
    return true;
  }
  bool operator != (const IteratorSetting &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const IteratorSetting & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(IteratorSetting &a, IteratorSetting &b);

inline std::ostream& operator<<(std::ostream& out, const IteratorSetting& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ScanOptions__isset {
  _ScanOptions__isset() : authorizations(false), range(false), columns(false), iterators(false), bufferSize(false) {}
  bool authorizations :1;
  bool range :1;
  bool columns :1;
  bool iterators :1;
  bool bufferSize :1;
} _ScanOptions__isset;

class ScanOptions {
 public:

  ScanOptions(const ScanOptions&);
  ScanOptions& operator=(const ScanOptions&);
  ScanOptions() : bufferSize(0) {
  }

  virtual ~ScanOptions() throw();
  std::set<std::string>  authorizations;
  Range range;
  std::vector<ScanColumn>  columns;
  std::vector<IteratorSetting>  iterators;
  int32_t bufferSize;

  _ScanOptions__isset __isset;

  void __set_authorizations(const std::set<std::string> & val);

  void __set_range(const Range& val);

  void __set_columns(const std::vector<ScanColumn> & val);

  void __set_iterators(const std::vector<IteratorSetting> & val);

  void __set_bufferSize(const int32_t val);

  bool operator == (const ScanOptions & rhs) const
  {
    if (__isset.authorizations != rhs.__isset.authorizations)
      return false;
    else if (__isset.authorizations && !(authorizations == rhs.authorizations))
      return false;
    if (__isset.range != rhs.__isset.range)
      return false;
    else if (__isset.range && !(range == rhs.range))
      return false;
    if (__isset.columns != rhs.__isset.columns)
      return false;
    else if (__isset.columns && !(columns == rhs.columns))
      return false;
    if (__isset.iterators != rhs.__isset.iterators)
      return false;
    else if (__isset.iterators && !(iterators == rhs.iterators))
      return false;
    if (__isset.bufferSize != rhs.__isset.bufferSize)
      return false;
    else if (__isset.bufferSize && !(bufferSize == rhs.bufferSize))
      return false;
    return true;
  }
  bool operator != (const ScanOptions &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ScanOptions & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ScanOptions &a, ScanOptions &b);

inline std::ostream& operator<<(std::ostream& out, const ScanOptions& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _BatchScanOptions__isset {
  _BatchScanOptions__isset() : authorizations(false), ranges(false), columns(false), iterators(false), threads(false) {}
  bool authorizations :1;
  bool ranges :1;
  bool columns :1;
  bool iterators :1;
  bool threads :1;
} _BatchScanOptions__isset;

class BatchScanOptions {
 public:

  BatchScanOptions(const BatchScanOptions&);
  BatchScanOptions& operator=(const BatchScanOptions&);
  BatchScanOptions() : threads(0) {
  }

  virtual ~BatchScanOptions() throw();
  std::set<std::string>  authorizations;
  std::vector<Range>  ranges;
  std::vector<ScanColumn>  columns;
  std::vector<IteratorSetting>  iterators;
  int32_t threads;

  _BatchScanOptions__isset __isset;

  void __set_authorizations(const std::set<std::string> & val);

  void __set_ranges(const std::vector<Range> & val);

  void __set_columns(const std::vector<ScanColumn> & val);

  void __set_iterators(const std::vector<IteratorSetting> & val);

  void __set_threads(const int32_t val);

  bool operator == (const BatchScanOptions & rhs) const
  {
    if (__isset.authorizations != rhs.__isset.authorizations)
      return false;
    else if (__isset.authorizations && !(authorizations == rhs.authorizations))
      return false;
    if (__isset.ranges != rhs.__isset.ranges)
      return false;
    else if (__isset.ranges && !(ranges == rhs.ranges))
      return false;
    if (__isset.columns != rhs.__isset.columns)
      return false;
    else if (__isset.columns && !(columns == rhs.columns))
      return false;
    if (__isset.iterators != rhs.__isset.iterators)
      return false;
    else if (__isset.iterators && !(iterators == rhs.iterators))
      return false;
    if (__isset.threads != rhs.__isset.threads)
      return false;
    else if (__isset.threads && !(threads == rhs.threads))
      return false;
    return true;
  }
  bool operator != (const BatchScanOptions &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const BatchScanOptions & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(BatchScanOptions &a, BatchScanOptions &b);

inline std::ostream& operator<<(std::ostream& out, const BatchScanOptions& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _KeyValueAndPeek__isset {
  _KeyValueAndPeek__isset() : keyValue(false), hasNext(false) {}
  bool keyValue :1;
  bool hasNext :1;
} _KeyValueAndPeek__isset;

class KeyValueAndPeek {
 public:

  KeyValueAndPeek(const KeyValueAndPeek&);
  KeyValueAndPeek& operator=(const KeyValueAndPeek&);
  KeyValueAndPeek() : hasNext(0) {
  }

  virtual ~KeyValueAndPeek() throw();
  KeyValue keyValue;
  bool hasNext;

  _KeyValueAndPeek__isset __isset;

  void __set_keyValue(const KeyValue& val);

  void __set_hasNext(const bool val);

  bool operator == (const KeyValueAndPeek & rhs) const
  {
    if (!(keyValue == rhs.keyValue))
      return false;
    if (!(hasNext == rhs.hasNext))
      return false;
    return true;
  }
  bool operator != (const KeyValueAndPeek &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const KeyValueAndPeek & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(KeyValueAndPeek &a, KeyValueAndPeek &b);

inline std::ostream& operator<<(std::ostream& out, const KeyValueAndPeek& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _KeyExtent__isset {
  _KeyExtent__isset() : tableId(false), endRow(false), prevEndRow(false) {}
  bool tableId :1;
  bool endRow :1;
  bool prevEndRow :1;
} _KeyExtent__isset;

class KeyExtent {
 public:

  KeyExtent(const KeyExtent&);
  KeyExtent& operator=(const KeyExtent&);
  KeyExtent() : tableId(), endRow(), prevEndRow() {
  }

  virtual ~KeyExtent() throw();
  std::string tableId;
  std::string endRow;
  std::string prevEndRow;

  _KeyExtent__isset __isset;

  void __set_tableId(const std::string& val);

  void __set_endRow(const std::string& val);

  void __set_prevEndRow(const std::string& val);

  bool operator == (const KeyExtent & rhs) const
  {
    if (!(tableId == rhs.tableId))
      return false;
    if (!(endRow == rhs.endRow))
      return false;
    if (!(prevEndRow == rhs.prevEndRow))
      return false;
    return true;
  }
  bool operator != (const KeyExtent &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const KeyExtent & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(KeyExtent &a, KeyExtent &b);

inline std::ostream& operator<<(std::ostream& out, const KeyExtent& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _Column__isset {
  _Column__isset() : colFamily(false), colQualifier(false), colVisibility(false) {}
  bool colFamily :1;
  bool colQualifier :1;
  bool colVisibility :1;
} _Column__isset;

class Column {
 public:

  Column(const Column&);
  Column& operator=(const Column&);
  Column() : colFamily(), colQualifier(), colVisibility() {
  }

  virtual ~Column() throw();
  std::string colFamily;
  std::string colQualifier;
  std::string colVisibility;

  _Column__isset __isset;

  void __set_colFamily(const std::string& val);

  void __set_colQualifier(const std::string& val);

  void __set_colVisibility(const std::string& val);

  bool operator == (const Column & rhs) const
  {
    if (!(colFamily == rhs.colFamily))
      return false;
    if (!(colQualifier == rhs.colQualifier))
      return false;
    if (!(colVisibility == rhs.colVisibility))
      return false;
    return true;
  }
  bool operator != (const Column &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Column & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Column &a, Column &b);

inline std::ostream& operator<<(std::ostream& out, const Column& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _Condition__isset {
  _Condition__isset() : column(false), timestamp(false), value(false), iterators(false) {}
  bool column :1;
  bool timestamp :1;
  bool value :1;
  bool iterators :1;
} _Condition__isset;

class Condition {
 public:

  Condition(const Condition&);
  Condition& operator=(const Condition&);
  Condition() : timestamp(0), value() {
  }

  virtual ~Condition() throw();
  Column column;
  int64_t timestamp;
  std::string value;
  std::vector<IteratorSetting>  iterators;

  _Condition__isset __isset;

  void __set_column(const Column& val);

  void __set_timestamp(const int64_t val);

  void __set_value(const std::string& val);

  void __set_iterators(const std::vector<IteratorSetting> & val);

  bool operator == (const Condition & rhs) const
  {
    if (!(column == rhs.column))
      return false;
    if (__isset.timestamp != rhs.__isset.timestamp)
      return false;
    else if (__isset.timestamp && !(timestamp == rhs.timestamp))
      return false;
    if (__isset.value != rhs.__isset.value)
      return false;
    else if (__isset.value && !(value == rhs.value))
      return false;
    if (__isset.iterators != rhs.__isset.iterators)
      return false;
    else if (__isset.iterators && !(iterators == rhs.iterators))
      return false;
    return true;
  }
  bool operator != (const Condition &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Condition & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(Condition &a, Condition &b);

inline std::ostream& operator<<(std::ostream& out, const Condition& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ConditionalUpdates__isset {
  _ConditionalUpdates__isset() : conditions(false), updates(false) {}
  bool conditions :1;
  bool updates :1;
} _ConditionalUpdates__isset;

class ConditionalUpdates {
 public:

  ConditionalUpdates(const ConditionalUpdates&);
  ConditionalUpdates& operator=(const ConditionalUpdates&);
  ConditionalUpdates() {
  }

  virtual ~ConditionalUpdates() throw();
  std::vector<Condition>  conditions;
  std::vector<ColumnUpdate>  updates;

  _ConditionalUpdates__isset __isset;

  void __set_conditions(const std::vector<Condition> & val);

  void __set_updates(const std::vector<ColumnUpdate> & val);

  bool operator == (const ConditionalUpdates & rhs) const
  {
    if (!(conditions == rhs.conditions))
      return false;
    if (!(updates == rhs.updates))
      return false;
    return true;
  }
  bool operator != (const ConditionalUpdates &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ConditionalUpdates & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ConditionalUpdates &a, ConditionalUpdates &b);

inline std::ostream& operator<<(std::ostream& out, const ConditionalUpdates& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ConditionalWriterOptions__isset {
  _ConditionalWriterOptions__isset() : maxMemory(false), timeoutMs(false), threads(false), authorizations(false), durability(false) {}
  bool maxMemory :1;
  bool timeoutMs :1;
  bool threads :1;
  bool authorizations :1;
  bool durability :1;
} _ConditionalWriterOptions__isset;

class ConditionalWriterOptions {
 public:

  ConditionalWriterOptions(const ConditionalWriterOptions&);
  ConditionalWriterOptions& operator=(const ConditionalWriterOptions&);
  ConditionalWriterOptions() : maxMemory(0), timeoutMs(0), threads(0), durability((Durability::type)0) {
  }

  virtual ~ConditionalWriterOptions() throw();
  int64_t maxMemory;
  int64_t timeoutMs;
  int32_t threads;
  std::set<std::string>  authorizations;
  Durability::type durability;

  _ConditionalWriterOptions__isset __isset;

  void __set_maxMemory(const int64_t val);

  void __set_timeoutMs(const int64_t val);

  void __set_threads(const int32_t val);

  void __set_authorizations(const std::set<std::string> & val);

  void __set_durability(const Durability::type val);

  bool operator == (const ConditionalWriterOptions & rhs) const
  {
    if (__isset.maxMemory != rhs.__isset.maxMemory)
      return false;
    else if (__isset.maxMemory && !(maxMemory == rhs.maxMemory))
      return false;
    if (__isset.timeoutMs != rhs.__isset.timeoutMs)
      return false;
    else if (__isset.timeoutMs && !(timeoutMs == rhs.timeoutMs))
      return false;
    if (__isset.threads != rhs.__isset.threads)
      return false;
    else if (__isset.threads && !(threads == rhs.threads))
      return false;
    if (__isset.authorizations != rhs.__isset.authorizations)
      return false;
    else if (__isset.authorizations && !(authorizations == rhs.authorizations))
      return false;
    if (__isset.durability != rhs.__isset.durability)
      return false;
    else if (__isset.durability && !(durability == rhs.durability))
      return false;
    return true;
  }
  bool operator != (const ConditionalWriterOptions &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ConditionalWriterOptions & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ConditionalWriterOptions &a, ConditionalWriterOptions &b);

inline std::ostream& operator<<(std::ostream& out, const ConditionalWriterOptions& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ActiveScan__isset {
  _ActiveScan__isset() : client(false), user(false), table(false), age(false), idleTime(false), type(false), state(false), extent(false), columns(false), iterators(false), authorizations(false) {}
  bool client :1;
  bool user :1;
  bool table :1;
  bool age :1;
  bool idleTime :1;
  bool type :1;
  bool state :1;
  bool extent :1;
  bool columns :1;
  bool iterators :1;
  bool authorizations :1;
} _ActiveScan__isset;

class ActiveScan {
 public:

  ActiveScan(const ActiveScan&);
  ActiveScan& operator=(const ActiveScan&);
  ActiveScan() : client(), user(), table(), age(0), idleTime(0), type((ScanType::type)0), state((ScanState::type)0) {
  }

  virtual ~ActiveScan() throw();
  std::string client;
  std::string user;
  std::string table;
  int64_t age;
  int64_t idleTime;
  ScanType::type type;
  ScanState::type state;
  KeyExtent extent;
  std::vector<Column>  columns;
  std::vector<IteratorSetting>  iterators;
  std::vector<std::string>  authorizations;

  _ActiveScan__isset __isset;

  void __set_client(const std::string& val);

  void __set_user(const std::string& val);

  void __set_table(const std::string& val);

  void __set_age(const int64_t val);

  void __set_idleTime(const int64_t val);

  void __set_type(const ScanType::type val);

  void __set_state(const ScanState::type val);

  void __set_extent(const KeyExtent& val);

  void __set_columns(const std::vector<Column> & val);

  void __set_iterators(const std::vector<IteratorSetting> & val);

  void __set_authorizations(const std::vector<std::string> & val);

  bool operator == (const ActiveScan & rhs) const
  {
    if (!(client == rhs.client))
      return false;
    if (!(user == rhs.user))
      return false;
    if (!(table == rhs.table))
      return false;
    if (!(age == rhs.age))
      return false;
    if (!(idleTime == rhs.idleTime))
      return false;
    if (!(type == rhs.type))
      return false;
    if (!(state == rhs.state))
      return false;
    if (!(extent == rhs.extent))
      return false;
    if (!(columns == rhs.columns))
      return false;
    if (!(iterators == rhs.iterators))
      return false;
    if (!(authorizations == rhs.authorizations))
      return false;
    return true;
  }
  bool operator != (const ActiveScan &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ActiveScan & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ActiveScan &a, ActiveScan &b);

inline std::ostream& operator<<(std::ostream& out, const ActiveScan& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _ActiveCompaction__isset {
  _ActiveCompaction__isset() : extent(false), age(false), inputFiles(false), outputFile(false), type(false), reason(false), localityGroup(false), entriesRead(false), entriesWritten(false), iterators(false) {}
  bool extent :1;
  bool age :1;
  bool inputFiles :1;
  bool outputFile :1;
  bool type :1;
  bool reason :1;
  bool localityGroup :1;
  bool entriesRead :1;
  bool entriesWritten :1;
  bool iterators :1;
} _ActiveCompaction__isset;

class ActiveCompaction {
 public:

  ActiveCompaction(const ActiveCompaction&);
  ActiveCompaction& operator=(const ActiveCompaction&);
  ActiveCompaction() : age(0), outputFile(), type((CompactionType::type)0), reason((CompactionReason::type)0), localityGroup(), entriesRead(0), entriesWritten(0) {
  }

  virtual ~ActiveCompaction() throw();
  KeyExtent extent;
  int64_t age;
  std::vector<std::string>  inputFiles;
  std::string outputFile;
  CompactionType::type type;
  CompactionReason::type reason;
  std::string localityGroup;
  int64_t entriesRead;
  int64_t entriesWritten;
  std::vector<IteratorSetting>  iterators;

  _ActiveCompaction__isset __isset;

  void __set_extent(const KeyExtent& val);

  void __set_age(const int64_t val);

  void __set_inputFiles(const std::vector<std::string> & val);

  void __set_outputFile(const std::string& val);

  void __set_type(const CompactionType::type val);

  void __set_reason(const CompactionReason::type val);

  void __set_localityGroup(const std::string& val);

  void __set_entriesRead(const int64_t val);

  void __set_entriesWritten(const int64_t val);

  void __set_iterators(const std::vector<IteratorSetting> & val);

  bool operator == (const ActiveCompaction & rhs) const
  {
    if (!(extent == rhs.extent))
      return false;
    if (!(age == rhs.age))
      return false;
    if (!(inputFiles == rhs.inputFiles))
      return false;
    if (!(outputFile == rhs.outputFile))
      return false;
    if (!(type == rhs.type))
      return false;
    if (!(reason == rhs.reason))
      return false;
    if (!(localityGroup == rhs.localityGroup))
      return false;
    if (!(entriesRead == rhs.entriesRead))
      return false;
    if (!(entriesWritten == rhs.entriesWritten))
      return false;
    if (!(iterators == rhs.iterators))
      return false;
    return true;
  }
  bool operator != (const ActiveCompaction &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ActiveCompaction & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(ActiveCompaction &a, ActiveCompaction &b);

inline std::ostream& operator<<(std::ostream& out, const ActiveCompaction& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _WriterOptions__isset {
  _WriterOptions__isset() : maxMemory(false), latencyMs(false), timeoutMs(false), threads(false), durability(false) {}
  bool maxMemory :1;
  bool latencyMs :1;
  bool timeoutMs :1;
  bool threads :1;
  bool durability :1;
} _WriterOptions__isset;

class WriterOptions {
 public:

  WriterOptions(const WriterOptions&);
  WriterOptions& operator=(const WriterOptions&);
  WriterOptions() : maxMemory(0), latencyMs(0), timeoutMs(0), threads(0), durability((Durability::type)0) {
  }

  virtual ~WriterOptions() throw();
  int64_t maxMemory;
  int64_t latencyMs;
  int64_t timeoutMs;
  int32_t threads;
  Durability::type durability;

  _WriterOptions__isset __isset;

  void __set_maxMemory(const int64_t val);

  void __set_latencyMs(const int64_t val);

  void __set_timeoutMs(const int64_t val);

  void __set_threads(const int32_t val);

  void __set_durability(const Durability::type val);

  bool operator == (const WriterOptions & rhs) const
  {
    if (!(maxMemory == rhs.maxMemory))
      return false;
    if (!(latencyMs == rhs.latencyMs))
      return false;
    if (!(timeoutMs == rhs.timeoutMs))
      return false;
    if (!(threads == rhs.threads))
      return false;
    if (__isset.durability != rhs.__isset.durability)
      return false;
    else if (__isset.durability && !(durability == rhs.durability))
      return false;
    return true;
  }
  bool operator != (const WriterOptions &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const WriterOptions & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(WriterOptions &a, WriterOptions &b);

inline std::ostream& operator<<(std::ostream& out, const WriterOptions& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _CompactionStrategyConfig__isset {
  _CompactionStrategyConfig__isset() : className(false), options(false) {}
  bool className :1;
  bool options :1;
} _CompactionStrategyConfig__isset;

class CompactionStrategyConfig {
 public:

  CompactionStrategyConfig(const CompactionStrategyConfig&);
  CompactionStrategyConfig& operator=(const CompactionStrategyConfig&);
  CompactionStrategyConfig() : className() {
  }

  virtual ~CompactionStrategyConfig() throw();
  std::string className;
  std::map<std::string, std::string>  options;

  _CompactionStrategyConfig__isset __isset;

  void __set_className(const std::string& val);

  void __set_options(const std::map<std::string, std::string> & val);

  bool operator == (const CompactionStrategyConfig & rhs) const
  {
    if (!(className == rhs.className))
      return false;
    if (!(options == rhs.options))
      return false;
    return true;
  }
  bool operator != (const CompactionStrategyConfig &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const CompactionStrategyConfig & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
};

void swap(CompactionStrategyConfig &a, CompactionStrategyConfig &b);

inline std::ostream& operator<<(std::ostream& out, const CompactionStrategyConfig& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _UnknownScanner__isset {
  _UnknownScanner__isset() : msg(false) {}
  bool msg :1;
} _UnknownScanner__isset;

class UnknownScanner : public ::apache::thrift::TException {
 public:

  UnknownScanner(const UnknownScanner&);
  UnknownScanner& operator=(const UnknownScanner&);
  UnknownScanner() : msg() {
  }

  virtual ~UnknownScanner() throw();
  std::string msg;

  _UnknownScanner__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const UnknownScanner & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const UnknownScanner &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const UnknownScanner & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(UnknownScanner &a, UnknownScanner &b);

inline std::ostream& operator<<(std::ostream& out, const UnknownScanner& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _UnknownWriter__isset {
  _UnknownWriter__isset() : msg(false) {}
  bool msg :1;
} _UnknownWriter__isset;

class UnknownWriter : public ::apache::thrift::TException {
 public:

  UnknownWriter(const UnknownWriter&);
  UnknownWriter& operator=(const UnknownWriter&);
  UnknownWriter() : msg() {
  }

  virtual ~UnknownWriter() throw();
  std::string msg;

  _UnknownWriter__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const UnknownWriter & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const UnknownWriter &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const UnknownWriter & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(UnknownWriter &a, UnknownWriter &b);

inline std::ostream& operator<<(std::ostream& out, const UnknownWriter& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _NoMoreEntriesException__isset {
  _NoMoreEntriesException__isset() : msg(false) {}
  bool msg :1;
} _NoMoreEntriesException__isset;

class NoMoreEntriesException : public ::apache::thrift::TException {
 public:

  NoMoreEntriesException(const NoMoreEntriesException&);
  NoMoreEntriesException& operator=(const NoMoreEntriesException&);
  NoMoreEntriesException() : msg() {
  }

  virtual ~NoMoreEntriesException() throw();
  std::string msg;

  _NoMoreEntriesException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const NoMoreEntriesException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const NoMoreEntriesException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const NoMoreEntriesException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(NoMoreEntriesException &a, NoMoreEntriesException &b);

inline std::ostream& operator<<(std::ostream& out, const NoMoreEntriesException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _AccumuloException__isset {
  _AccumuloException__isset() : msg(false) {}
  bool msg :1;
} _AccumuloException__isset;

class AccumuloException : public ::apache::thrift::TException {
 public:

  AccumuloException(const AccumuloException&);
  AccumuloException& operator=(const AccumuloException&);
  AccumuloException() : msg() {
  }

  virtual ~AccumuloException() throw();
  std::string msg;

  _AccumuloException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const AccumuloException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const AccumuloException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(AccumuloException &a, AccumuloException &b);

inline std::ostream& operator<<(std::ostream& out, const AccumuloException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _AccumuloSecurityException__isset {
  _AccumuloSecurityException__isset() : msg(false) {}
  bool msg :1;
} _AccumuloSecurityException__isset;

class AccumuloSecurityException : public ::apache::thrift::TException {
 public:

  AccumuloSecurityException(const AccumuloSecurityException&);
  AccumuloSecurityException& operator=(const AccumuloSecurityException&);
  AccumuloSecurityException() : msg() {
  }

  virtual ~AccumuloSecurityException() throw();
  std::string msg;

  _AccumuloSecurityException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const AccumuloSecurityException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const AccumuloSecurityException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const AccumuloSecurityException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(AccumuloSecurityException &a, AccumuloSecurityException &b);

inline std::ostream& operator<<(std::ostream& out, const AccumuloSecurityException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _TableNotFoundException__isset {
  _TableNotFoundException__isset() : msg(false) {}
  bool msg :1;
} _TableNotFoundException__isset;

class TableNotFoundException : public ::apache::thrift::TException {
 public:

  TableNotFoundException(const TableNotFoundException&);
  TableNotFoundException& operator=(const TableNotFoundException&);
  TableNotFoundException() : msg() {
  }

  virtual ~TableNotFoundException() throw();
  std::string msg;

  _TableNotFoundException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const TableNotFoundException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const TableNotFoundException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const TableNotFoundException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(TableNotFoundException &a, TableNotFoundException &b);

inline std::ostream& operator<<(std::ostream& out, const TableNotFoundException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _TableExistsException__isset {
  _TableExistsException__isset() : msg(false) {}
  bool msg :1;
} _TableExistsException__isset;

class TableExistsException : public ::apache::thrift::TException {
 public:

  TableExistsException(const TableExistsException&);
  TableExistsException& operator=(const TableExistsException&);
  TableExistsException() : msg() {
  }

  virtual ~TableExistsException() throw();
  std::string msg;

  _TableExistsException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const TableExistsException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const TableExistsException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const TableExistsException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(TableExistsException &a, TableExistsException &b);

inline std::ostream& operator<<(std::ostream& out, const TableExistsException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _MutationsRejectedException__isset {
  _MutationsRejectedException__isset() : msg(false) {}
  bool msg :1;
} _MutationsRejectedException__isset;

class MutationsRejectedException : public ::apache::thrift::TException {
 public:

  MutationsRejectedException(const MutationsRejectedException&);
  MutationsRejectedException& operator=(const MutationsRejectedException&);
  MutationsRejectedException() : msg() {
  }

  virtual ~MutationsRejectedException() throw();
  std::string msg;

  _MutationsRejectedException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const MutationsRejectedException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const MutationsRejectedException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const MutationsRejectedException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(MutationsRejectedException &a, MutationsRejectedException &b);

inline std::ostream& operator<<(std::ostream& out, const MutationsRejectedException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _NamespaceExistsException__isset {
  _NamespaceExistsException__isset() : msg(false) {}
  bool msg :1;
} _NamespaceExistsException__isset;

class NamespaceExistsException : public ::apache::thrift::TException {
 public:

  NamespaceExistsException(const NamespaceExistsException&);
  NamespaceExistsException& operator=(const NamespaceExistsException&);
  NamespaceExistsException() : msg() {
  }

  virtual ~NamespaceExistsException() throw();
  std::string msg;

  _NamespaceExistsException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const NamespaceExistsException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const NamespaceExistsException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const NamespaceExistsException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(NamespaceExistsException &a, NamespaceExistsException &b);

inline std::ostream& operator<<(std::ostream& out, const NamespaceExistsException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _NamespaceNotFoundException__isset {
  _NamespaceNotFoundException__isset() : msg(false) {}
  bool msg :1;
} _NamespaceNotFoundException__isset;

class NamespaceNotFoundException : public ::apache::thrift::TException {
 public:

  NamespaceNotFoundException(const NamespaceNotFoundException&);
  NamespaceNotFoundException& operator=(const NamespaceNotFoundException&);
  NamespaceNotFoundException() : msg() {
  }

  virtual ~NamespaceNotFoundException() throw();
  std::string msg;

  _NamespaceNotFoundException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const NamespaceNotFoundException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const NamespaceNotFoundException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const NamespaceNotFoundException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(NamespaceNotFoundException &a, NamespaceNotFoundException &b);

inline std::ostream& operator<<(std::ostream& out, const NamespaceNotFoundException& obj)
{
  obj.printTo(out);
  return out;
}

typedef struct _NamespaceNotEmptyException__isset {
  _NamespaceNotEmptyException__isset() : msg(false) {}
  bool msg :1;
} _NamespaceNotEmptyException__isset;

class NamespaceNotEmptyException : public ::apache::thrift::TException {
 public:

  NamespaceNotEmptyException(const NamespaceNotEmptyException&);
  NamespaceNotEmptyException& operator=(const NamespaceNotEmptyException&);
  NamespaceNotEmptyException() : msg() {
  }

  virtual ~NamespaceNotEmptyException() throw();
  std::string msg;

  _NamespaceNotEmptyException__isset __isset;

  void __set_msg(const std::string& val);

  bool operator == (const NamespaceNotEmptyException & rhs) const
  {
    if (!(msg == rhs.msg))
      return false;
    return true;
  }
  bool operator != (const NamespaceNotEmptyException &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const NamespaceNotEmptyException & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

  virtual void printTo(std::ostream& out) const;
  mutable std::string thriftTExceptionMessageHolder_;
  const char* what() const throw();
};

void swap(NamespaceNotEmptyException &a, NamespaceNotEmptyException &b);

inline std::ostream& operator<<(std::ostream& out, const NamespaceNotEmptyException& obj)
{
  obj.printTo(out);
  return out;
}

} // namespace

#endif
