/*
 * 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,
    CREATE_NAMESPACE = 8,
    DROP_NAMESPACE = 9,
    ALTER_NAMESPACE = 10,
    OBTAIN_DELEGATION_TOKEN = 11
  };
};

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
