/*
 * 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
 *
 *   https://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.17.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
#include "AccumuloProxy.h"

namespace accumulo {


AccumuloProxy_addConstraint_args::~AccumuloProxy_addConstraint_args() noexcept {
}


uint32_t AccumuloProxy_addConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->constraintClassName);
          this->__isset.constraintClassName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_addConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_addConstraint_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("constraintClassName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->constraintClassName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addConstraint_pargs::~AccumuloProxy_addConstraint_pargs() noexcept {
}


uint32_t AccumuloProxy_addConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_addConstraint_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("constraintClassName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->constraintClassName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addConstraint_result::~AccumuloProxy_addConstraint_result() noexcept {
}


uint32_t AccumuloProxy_addConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_addConstraint_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_addConstraint_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_I32, 0);
    xfer += oprot->writeI32(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addConstraint_presult::~AccumuloProxy_addConstraint_presult() noexcept {
}


uint32_t AccumuloProxy_addConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_addSplits_args::~AccumuloProxy_addSplits_args() noexcept {
}


uint32_t AccumuloProxy_addSplits_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->splits.clear();
            uint32_t _size195;
            ::apache::thrift::protocol::TType _etype198;
            xfer += iprot->readSetBegin(_etype198, _size195);
            uint32_t _i199;
            for (_i199 = 0; _i199 < _size195; ++_i199)
            {
              std::string _elem200;
              xfer += iprot->readBinary(_elem200);
              this->splits.insert(_elem200);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.splits = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_addSplits_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_addSplits_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("splits", ::apache::thrift::protocol::T_SET, 3);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->splits.size()));
    std::set<std::string> ::const_iterator _iter201;
    for (_iter201 = this->splits.begin(); _iter201 != this->splits.end(); ++_iter201)
    {
      xfer += oprot->writeBinary((*_iter201));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addSplits_pargs::~AccumuloProxy_addSplits_pargs() noexcept {
}


uint32_t AccumuloProxy_addSplits_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_addSplits_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("splits", ::apache::thrift::protocol::T_SET, 3);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->splits)).size()));
    std::set<std::string> ::const_iterator _iter202;
    for (_iter202 = (*(this->splits)).begin(); _iter202 != (*(this->splits)).end(); ++_iter202)
    {
      xfer += oprot->writeBinary((*_iter202));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addSplits_result::~AccumuloProxy_addSplits_result() noexcept {
}


uint32_t AccumuloProxy_addSplits_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_addSplits_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_addSplits_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addSplits_presult::~AccumuloProxy_addSplits_presult() noexcept {
}


uint32_t AccumuloProxy_addSplits_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_attachIterator_args::~AccumuloProxy_attachIterator_args() noexcept {
}


uint32_t AccumuloProxy_attachIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->setting.read(iprot);
          this->__isset.setting = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->scopes.clear();
            uint32_t _size203;
            ::apache::thrift::protocol::TType _etype206;
            xfer += iprot->readSetBegin(_etype206, _size203);
            uint32_t _i207;
            for (_i207 = 0; _i207 < _size203; ++_i207)
            {
              IteratorScope::type _elem208;
              int32_t ecast209;
              xfer += iprot->readI32(ecast209);
              _elem208 = static_cast<IteratorScope::type>(ecast209);
              this->scopes.insert(_elem208);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.scopes = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_attachIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_attachIterator_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->setting.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
    std::set<IteratorScope::type> ::const_iterator _iter210;
    for (_iter210 = this->scopes.begin(); _iter210 != this->scopes.end(); ++_iter210)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter210)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_attachIterator_pargs::~AccumuloProxy_attachIterator_pargs() noexcept {
}


uint32_t AccumuloProxy_attachIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_attachIterator_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->setting)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
    std::set<IteratorScope::type> ::const_iterator _iter211;
    for (_iter211 = (*(this->scopes)).begin(); _iter211 != (*(this->scopes)).end(); ++_iter211)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter211)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_attachIterator_result::~AccumuloProxy_attachIterator_result() noexcept {
}


uint32_t AccumuloProxy_attachIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_attachIterator_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_attachIterator_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_attachIterator_presult::~AccumuloProxy_attachIterator_presult() noexcept {
}


uint32_t AccumuloProxy_attachIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_checkIteratorConflicts_args::~AccumuloProxy_checkIteratorConflicts_args() noexcept {
}


uint32_t AccumuloProxy_checkIteratorConflicts_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->setting.read(iprot);
          this->__isset.setting = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->scopes.clear();
            uint32_t _size212;
            ::apache::thrift::protocol::TType _etype215;
            xfer += iprot->readSetBegin(_etype215, _size212);
            uint32_t _i216;
            for (_i216 = 0; _i216 < _size212; ++_i216)
            {
              IteratorScope::type _elem217;
              int32_t ecast218;
              xfer += iprot->readI32(ecast218);
              _elem217 = static_cast<IteratorScope::type>(ecast218);
              this->scopes.insert(_elem217);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.scopes = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_checkIteratorConflicts_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_checkIteratorConflicts_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->setting.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
    std::set<IteratorScope::type> ::const_iterator _iter219;
    for (_iter219 = this->scopes.begin(); _iter219 != this->scopes.end(); ++_iter219)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter219)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_checkIteratorConflicts_pargs::~AccumuloProxy_checkIteratorConflicts_pargs() noexcept {
}


uint32_t AccumuloProxy_checkIteratorConflicts_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_checkIteratorConflicts_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->setting)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
    std::set<IteratorScope::type> ::const_iterator _iter220;
    for (_iter220 = (*(this->scopes)).begin(); _iter220 != (*(this->scopes)).end(); ++_iter220)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter220)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_checkIteratorConflicts_result::~AccumuloProxy_checkIteratorConflicts_result() noexcept {
}


uint32_t AccumuloProxy_checkIteratorConflicts_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_checkIteratorConflicts_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_checkIteratorConflicts_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_checkIteratorConflicts_presult::~AccumuloProxy_checkIteratorConflicts_presult() noexcept {
}


uint32_t AccumuloProxy_checkIteratorConflicts_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_clearLocatorCache_args::~AccumuloProxy_clearLocatorCache_args() noexcept {
}


uint32_t AccumuloProxy_clearLocatorCache_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_clearLocatorCache_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_clearLocatorCache_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_clearLocatorCache_pargs::~AccumuloProxy_clearLocatorCache_pargs() noexcept {
}


uint32_t AccumuloProxy_clearLocatorCache_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_clearLocatorCache_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_clearLocatorCache_result::~AccumuloProxy_clearLocatorCache_result() noexcept {
}


uint32_t AccumuloProxy_clearLocatorCache_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_clearLocatorCache_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_clearLocatorCache_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_clearLocatorCache_presult::~AccumuloProxy_clearLocatorCache_presult() noexcept {
}


uint32_t AccumuloProxy_clearLocatorCache_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_cloneTable_args::~AccumuloProxy_cloneTable_args() noexcept {
}


uint32_t AccumuloProxy_cloneTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->newTableName);
          this->__isset.newTableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->flush);
          this->__isset.flush = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 5:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->propertiesToSet.clear();
            uint32_t _size221;
            ::apache::thrift::protocol::TType _ktype222;
            ::apache::thrift::protocol::TType _vtype223;
            xfer += iprot->readMapBegin(_ktype222, _vtype223, _size221);
            uint32_t _i225;
            for (_i225 = 0; _i225 < _size221; ++_i225)
            {
              std::string _key226;
              xfer += iprot->readString(_key226);
              std::string& _val227 = this->propertiesToSet[_key226];
              xfer += iprot->readString(_val227);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.propertiesToSet = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 6:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->propertiesToExclude.clear();
            uint32_t _size228;
            ::apache::thrift::protocol::TType _etype231;
            xfer += iprot->readSetBegin(_etype231, _size228);
            uint32_t _i232;
            for (_i232 = 0; _i232 < _size228; ++_i232)
            {
              std::string _elem233;
              xfer += iprot->readString(_elem233);
              this->propertiesToExclude.insert(_elem233);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.propertiesToExclude = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_cloneTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_cloneTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("newTableName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->newTableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("flush", ::apache::thrift::protocol::T_BOOL, 4);
  xfer += oprot->writeBool(this->flush);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("propertiesToSet", ::apache::thrift::protocol::T_MAP, 5);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->propertiesToSet.size()));
    std::map<std::string, std::string> ::const_iterator _iter234;
    for (_iter234 = this->propertiesToSet.begin(); _iter234 != this->propertiesToSet.end(); ++_iter234)
    {
      xfer += oprot->writeString(_iter234->first);
      xfer += oprot->writeString(_iter234->second);
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("propertiesToExclude", ::apache::thrift::protocol::T_SET, 6);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->propertiesToExclude.size()));
    std::set<std::string> ::const_iterator _iter235;
    for (_iter235 = this->propertiesToExclude.begin(); _iter235 != this->propertiesToExclude.end(); ++_iter235)
    {
      xfer += oprot->writeString((*_iter235));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_cloneTable_pargs::~AccumuloProxy_cloneTable_pargs() noexcept {
}


uint32_t AccumuloProxy_cloneTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_cloneTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("newTableName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->newTableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("flush", ::apache::thrift::protocol::T_BOOL, 4);
  xfer += oprot->writeBool((*(this->flush)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("propertiesToSet", ::apache::thrift::protocol::T_MAP, 5);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->propertiesToSet)).size()));
    std::map<std::string, std::string> ::const_iterator _iter236;
    for (_iter236 = (*(this->propertiesToSet)).begin(); _iter236 != (*(this->propertiesToSet)).end(); ++_iter236)
    {
      xfer += oprot->writeString(_iter236->first);
      xfer += oprot->writeString(_iter236->second);
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("propertiesToExclude", ::apache::thrift::protocol::T_SET, 6);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->propertiesToExclude)).size()));
    std::set<std::string> ::const_iterator _iter237;
    for (_iter237 = (*(this->propertiesToExclude)).begin(); _iter237 != (*(this->propertiesToExclude)).end(); ++_iter237)
    {
      xfer += oprot->writeString((*_iter237));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_cloneTable_result::~AccumuloProxy_cloneTable_result() noexcept {
}


uint32_t AccumuloProxy_cloneTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_cloneTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_cloneTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch4) {
    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
    xfer += this->ouch4.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_cloneTable_presult::~AccumuloProxy_cloneTable_presult() noexcept {
}


uint32_t AccumuloProxy_cloneTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_compactTable_args::~AccumuloProxy_compactTable_args() noexcept {
}


uint32_t AccumuloProxy_compactTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->startRow);
          this->__isset.startRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->endRow);
          this->__isset.endRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 5:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->iterators.clear();
            uint32_t _size238;
            ::apache::thrift::protocol::TType _etype241;
            xfer += iprot->readListBegin(_etype241, _size238);
            this->iterators.resize(_size238);
            uint32_t _i242;
            for (_i242 = 0; _i242 < _size238; ++_i242)
            {
              xfer += this->iterators[_i242].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.iterators = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 6:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->flush);
          this->__isset.flush = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 7:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->wait);
          this->__isset.wait = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 8:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->selectorConfig.read(iprot);
          this->__isset.selectorConfig = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 9:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->configurerConfig.read(iprot);
          this->__isset.configurerConfig = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_compactTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_compactTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->startRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary(this->endRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 5);
  {
    xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
    std::vector<IteratorSetting> ::const_iterator _iter243;
    for (_iter243 = this->iterators.begin(); _iter243 != this->iterators.end(); ++_iter243)
    {
      xfer += (*_iter243).write(oprot);
    }
    xfer += oprot->writeListEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("flush", ::apache::thrift::protocol::T_BOOL, 6);
  xfer += oprot->writeBool(this->flush);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 7);
  xfer += oprot->writeBool(this->wait);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("selectorConfig", ::apache::thrift::protocol::T_STRUCT, 8);
  xfer += this->selectorConfig.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("configurerConfig", ::apache::thrift::protocol::T_STRUCT, 9);
  xfer += this->configurerConfig.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_compactTable_pargs::~AccumuloProxy_compactTable_pargs() noexcept {
}


uint32_t AccumuloProxy_compactTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_compactTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->startRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary((*(this->endRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 5);
  {
    xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->iterators)).size()));
    std::vector<IteratorSetting> ::const_iterator _iter244;
    for (_iter244 = (*(this->iterators)).begin(); _iter244 != (*(this->iterators)).end(); ++_iter244)
    {
      xfer += (*_iter244).write(oprot);
    }
    xfer += oprot->writeListEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("flush", ::apache::thrift::protocol::T_BOOL, 6);
  xfer += oprot->writeBool((*(this->flush)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 7);
  xfer += oprot->writeBool((*(this->wait)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("selectorConfig", ::apache::thrift::protocol::T_STRUCT, 8);
  xfer += (*(this->selectorConfig)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("configurerConfig", ::apache::thrift::protocol::T_STRUCT, 9);
  xfer += (*(this->configurerConfig)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_compactTable_result::~AccumuloProxy_compactTable_result() noexcept {
}


uint32_t AccumuloProxy_compactTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_compactTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_compactTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_compactTable_presult::~AccumuloProxy_compactTable_presult() noexcept {
}


uint32_t AccumuloProxy_compactTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_cancelCompaction_args::~AccumuloProxy_cancelCompaction_args() noexcept {
}


uint32_t AccumuloProxy_cancelCompaction_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_cancelCompaction_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_cancelCompaction_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_cancelCompaction_pargs::~AccumuloProxy_cancelCompaction_pargs() noexcept {
}


uint32_t AccumuloProxy_cancelCompaction_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_cancelCompaction_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_cancelCompaction_result::~AccumuloProxy_cancelCompaction_result() noexcept {
}


uint32_t AccumuloProxy_cancelCompaction_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_cancelCompaction_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_cancelCompaction_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_cancelCompaction_presult::~AccumuloProxy_cancelCompaction_presult() noexcept {
}


uint32_t AccumuloProxy_cancelCompaction_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createTable_args::~AccumuloProxy_createTable_args() noexcept {
}


uint32_t AccumuloProxy_createTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->versioningIter);
          this->__isset.versioningIter = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast245;
          xfer += iprot->readI32(ecast245);
          this->type = static_cast<TimeType::type>(ecast245);
          this->__isset.type = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("versioningIter", ::apache::thrift::protocol::T_BOOL, 3);
  xfer += oprot->writeBool(this->versioningIter);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("type", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->type));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createTable_pargs::~AccumuloProxy_createTable_pargs() noexcept {
}


uint32_t AccumuloProxy_createTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("versioningIter", ::apache::thrift::protocol::T_BOOL, 3);
  xfer += oprot->writeBool((*(this->versioningIter)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("type", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->type))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createTable_result::~AccumuloProxy_createTable_result() noexcept {
}


uint32_t AccumuloProxy_createTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createTable_presult::~AccumuloProxy_createTable_presult() noexcept {
}


uint32_t AccumuloProxy_createTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_deleteTable_args::~AccumuloProxy_deleteTable_args() noexcept {
}


uint32_t AccumuloProxy_deleteTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_deleteTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_deleteTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteTable_pargs::~AccumuloProxy_deleteTable_pargs() noexcept {
}


uint32_t AccumuloProxy_deleteTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_deleteTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteTable_result::~AccumuloProxy_deleteTable_result() noexcept {
}


uint32_t AccumuloProxy_deleteTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_deleteTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_deleteTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteTable_presult::~AccumuloProxy_deleteTable_presult() noexcept {
}


uint32_t AccumuloProxy_deleteTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_deleteRows_args::~AccumuloProxy_deleteRows_args() noexcept {
}


uint32_t AccumuloProxy_deleteRows_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->startRow);
          this->__isset.startRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->endRow);
          this->__isset.endRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_deleteRows_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_deleteRows_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->startRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary(this->endRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteRows_pargs::~AccumuloProxy_deleteRows_pargs() noexcept {
}


uint32_t AccumuloProxy_deleteRows_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_deleteRows_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->startRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary((*(this->endRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteRows_result::~AccumuloProxy_deleteRows_result() noexcept {
}


uint32_t AccumuloProxy_deleteRows_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_deleteRows_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_deleteRows_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteRows_presult::~AccumuloProxy_deleteRows_presult() noexcept {
}


uint32_t AccumuloProxy_deleteRows_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_exportTable_args::~AccumuloProxy_exportTable_args() noexcept {
}


uint32_t AccumuloProxy_exportTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->exportDir);
          this->__isset.exportDir = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_exportTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_exportTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("exportDir", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->exportDir);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_exportTable_pargs::~AccumuloProxy_exportTable_pargs() noexcept {
}


uint32_t AccumuloProxy_exportTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_exportTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("exportDir", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->exportDir)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_exportTable_result::~AccumuloProxy_exportTable_result() noexcept {
}


uint32_t AccumuloProxy_exportTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_exportTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_exportTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_exportTable_presult::~AccumuloProxy_exportTable_presult() noexcept {
}


uint32_t AccumuloProxy_exportTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_flushTable_args::~AccumuloProxy_flushTable_args() noexcept {
}


uint32_t AccumuloProxy_flushTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->startRow);
          this->__isset.startRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->endRow);
          this->__isset.endRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 5:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->wait);
          this->__isset.wait = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_flushTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_flushTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->startRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary(this->endRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 5);
  xfer += oprot->writeBool(this->wait);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flushTable_pargs::~AccumuloProxy_flushTable_pargs() noexcept {
}


uint32_t AccumuloProxy_flushTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_flushTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->startRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary((*(this->endRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 5);
  xfer += oprot->writeBool((*(this->wait)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flushTable_result::~AccumuloProxy_flushTable_result() noexcept {
}


uint32_t AccumuloProxy_flushTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_flushTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_flushTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flushTable_presult::~AccumuloProxy_flushTable_presult() noexcept {
}


uint32_t AccumuloProxy_flushTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getDiskUsage_args::~AccumuloProxy_getDiskUsage_args() noexcept {
}


uint32_t AccumuloProxy_getDiskUsage_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->tables.clear();
            uint32_t _size246;
            ::apache::thrift::protocol::TType _etype249;
            xfer += iprot->readSetBegin(_etype249, _size246);
            uint32_t _i250;
            for (_i250 = 0; _i250 < _size246; ++_i250)
            {
              std::string _elem251;
              xfer += iprot->readString(_elem251);
              this->tables.insert(_elem251);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.tables = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getDiskUsage_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getDiskUsage_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tables", ::apache::thrift::protocol::T_SET, 2);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->tables.size()));
    std::set<std::string> ::const_iterator _iter252;
    for (_iter252 = this->tables.begin(); _iter252 != this->tables.end(); ++_iter252)
    {
      xfer += oprot->writeString((*_iter252));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getDiskUsage_pargs::~AccumuloProxy_getDiskUsage_pargs() noexcept {
}


uint32_t AccumuloProxy_getDiskUsage_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getDiskUsage_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tables", ::apache::thrift::protocol::T_SET, 2);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->tables)).size()));
    std::set<std::string> ::const_iterator _iter253;
    for (_iter253 = (*(this->tables)).begin(); _iter253 != (*(this->tables)).end(); ++_iter253)
    {
      xfer += oprot->writeString((*_iter253));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getDiskUsage_result::~AccumuloProxy_getDiskUsage_result() noexcept {
}


uint32_t AccumuloProxy_getDiskUsage_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size254;
            ::apache::thrift::protocol::TType _etype257;
            xfer += iprot->readListBegin(_etype257, _size254);
            this->success.resize(_size254);
            uint32_t _i258;
            for (_i258 = 0; _i258 < _size254; ++_i258)
            {
              xfer += this->success[_i258].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getDiskUsage_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getDiskUsage_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
      std::vector<DiskUsage> ::const_iterator _iter259;
      for (_iter259 = this->success.begin(); _iter259 != this->success.end(); ++_iter259)
      {
        xfer += (*_iter259).write(oprot);
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getDiskUsage_presult::~AccumuloProxy_getDiskUsage_presult() noexcept {
}


uint32_t AccumuloProxy_getDiskUsage_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size260;
            ::apache::thrift::protocol::TType _etype263;
            xfer += iprot->readListBegin(_etype263, _size260);
            (*(this->success)).resize(_size260);
            uint32_t _i264;
            for (_i264 = 0; _i264 < _size260; ++_i264)
            {
              xfer += (*(this->success))[_i264].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getLocalityGroups_args::~AccumuloProxy_getLocalityGroups_args() noexcept {
}


uint32_t AccumuloProxy_getLocalityGroups_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getLocalityGroups_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getLocalityGroups_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getLocalityGroups_pargs::~AccumuloProxy_getLocalityGroups_pargs() noexcept {
}


uint32_t AccumuloProxy_getLocalityGroups_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getLocalityGroups_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getLocalityGroups_result::~AccumuloProxy_getLocalityGroups_result() noexcept {
}


uint32_t AccumuloProxy_getLocalityGroups_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size265;
            ::apache::thrift::protocol::TType _ktype266;
            ::apache::thrift::protocol::TType _vtype267;
            xfer += iprot->readMapBegin(_ktype266, _vtype267, _size265);
            uint32_t _i269;
            for (_i269 = 0; _i269 < _size265; ++_i269)
            {
              std::string _key270;
              xfer += iprot->readString(_key270);
              std::set<std::string> & _val271 = this->success[_key270];
              {
                _val271.clear();
                uint32_t _size272;
                ::apache::thrift::protocol::TType _etype275;
                xfer += iprot->readSetBegin(_etype275, _size272);
                uint32_t _i276;
                for (_i276 = 0; _i276 < _size272; ++_i276)
                {
                  std::string _elem277;
                  xfer += iprot->readString(_elem277);
                  _val271.insert(_elem277);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getLocalityGroups_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getLocalityGroups_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::set<std::string> > ::const_iterator _iter278;
      for (_iter278 = this->success.begin(); _iter278 != this->success.end(); ++_iter278)
      {
        xfer += oprot->writeString(_iter278->first);
        {
          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter278->second.size()));
          std::set<std::string> ::const_iterator _iter279;
          for (_iter279 = _iter278->second.begin(); _iter279 != _iter278->second.end(); ++_iter279)
          {
            xfer += oprot->writeString((*_iter279));
          }
          xfer += oprot->writeSetEnd();
        }
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getLocalityGroups_presult::~AccumuloProxy_getLocalityGroups_presult() noexcept {
}


uint32_t AccumuloProxy_getLocalityGroups_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size280;
            ::apache::thrift::protocol::TType _ktype281;
            ::apache::thrift::protocol::TType _vtype282;
            xfer += iprot->readMapBegin(_ktype281, _vtype282, _size280);
            uint32_t _i284;
            for (_i284 = 0; _i284 < _size280; ++_i284)
            {
              std::string _key285;
              xfer += iprot->readString(_key285);
              std::set<std::string> & _val286 = (*(this->success))[_key285];
              {
                _val286.clear();
                uint32_t _size287;
                ::apache::thrift::protocol::TType _etype290;
                xfer += iprot->readSetBegin(_etype290, _size287);
                uint32_t _i291;
                for (_i291 = 0; _i291 < _size287; ++_i291)
                {
                  std::string _elem292;
                  xfer += iprot->readString(_elem292);
                  _val286.insert(_elem292);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getIteratorSetting_args::~AccumuloProxy_getIteratorSetting_args() noexcept {
}


uint32_t AccumuloProxy_getIteratorSetting_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->iteratorName);
          this->__isset.iteratorName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast293;
          xfer += iprot->readI32(ecast293);
          this->scope = static_cast<IteratorScope::type>(ecast293);
          this->__isset.scope = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getIteratorSetting_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getIteratorSetting_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("iteratorName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->iteratorName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scope", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->scope));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getIteratorSetting_pargs::~AccumuloProxy_getIteratorSetting_pargs() noexcept {
}


uint32_t AccumuloProxy_getIteratorSetting_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getIteratorSetting_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("iteratorName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->iteratorName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scope", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->scope))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getIteratorSetting_result::~AccumuloProxy_getIteratorSetting_result() noexcept {
}


uint32_t AccumuloProxy_getIteratorSetting_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->success.read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getIteratorSetting_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getIteratorSetting_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
    xfer += this->success.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getIteratorSetting_presult::~AccumuloProxy_getIteratorSetting_presult() noexcept {
}


uint32_t AccumuloProxy_getIteratorSetting_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += (*(this->success)).read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getMaxRow_args::~AccumuloProxy_getMaxRow_args() noexcept {
}


uint32_t AccumuloProxy_getMaxRow_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->auths.clear();
            uint32_t _size294;
            ::apache::thrift::protocol::TType _etype297;
            xfer += iprot->readSetBegin(_etype297, _size294);
            uint32_t _i298;
            for (_i298 = 0; _i298 < _size294; ++_i298)
            {
              std::string _elem299;
              xfer += iprot->readBinary(_elem299);
              this->auths.insert(_elem299);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.auths = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->startRow);
          this->__isset.startRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 5:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->startInclusive);
          this->__isset.startInclusive = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 6:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->endRow);
          this->__isset.endRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 7:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->endInclusive);
          this->__isset.endInclusive = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getMaxRow_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getMaxRow_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("auths", ::apache::thrift::protocol::T_SET, 3);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->auths.size()));
    std::set<std::string> ::const_iterator _iter300;
    for (_iter300 = this->auths.begin(); _iter300 != this->auths.end(); ++_iter300)
    {
      xfer += oprot->writeBinary((*_iter300));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary(this->startRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startInclusive", ::apache::thrift::protocol::T_BOOL, 5);
  xfer += oprot->writeBool(this->startInclusive);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 6);
  xfer += oprot->writeBinary(this->endRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endInclusive", ::apache::thrift::protocol::T_BOOL, 7);
  xfer += oprot->writeBool(this->endInclusive);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getMaxRow_pargs::~AccumuloProxy_getMaxRow_pargs() noexcept {
}


uint32_t AccumuloProxy_getMaxRow_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getMaxRow_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("auths", ::apache::thrift::protocol::T_SET, 3);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->auths)).size()));
    std::set<std::string> ::const_iterator _iter301;
    for (_iter301 = (*(this->auths)).begin(); _iter301 != (*(this->auths)).end(); ++_iter301)
    {
      xfer += oprot->writeBinary((*_iter301));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary((*(this->startRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startInclusive", ::apache::thrift::protocol::T_BOOL, 5);
  xfer += oprot->writeBool((*(this->startInclusive)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 6);
  xfer += oprot->writeBinary((*(this->endRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endInclusive", ::apache::thrift::protocol::T_BOOL, 7);
  xfer += oprot->writeBool((*(this->endInclusive)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getMaxRow_result::~AccumuloProxy_getMaxRow_result() noexcept {
}


uint32_t AccumuloProxy_getMaxRow_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getMaxRow_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getMaxRow_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeBinary(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getMaxRow_presult::~AccumuloProxy_getMaxRow_presult() noexcept {
}


uint32_t AccumuloProxy_getMaxRow_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getTableProperties_args::~AccumuloProxy_getTableProperties_args() noexcept {
}


uint32_t AccumuloProxy_getTableProperties_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getTableProperties_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getTableProperties_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getTableProperties_pargs::~AccumuloProxy_getTableProperties_pargs() noexcept {
}


uint32_t AccumuloProxy_getTableProperties_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getTableProperties_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getTableProperties_result::~AccumuloProxy_getTableProperties_result() noexcept {
}


uint32_t AccumuloProxy_getTableProperties_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size302;
            ::apache::thrift::protocol::TType _ktype303;
            ::apache::thrift::protocol::TType _vtype304;
            xfer += iprot->readMapBegin(_ktype303, _vtype304, _size302);
            uint32_t _i306;
            for (_i306 = 0; _i306 < _size302; ++_i306)
            {
              std::string _key307;
              xfer += iprot->readString(_key307);
              std::string& _val308 = this->success[_key307];
              xfer += iprot->readString(_val308);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getTableProperties_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getTableProperties_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::string> ::const_iterator _iter309;
      for (_iter309 = this->success.begin(); _iter309 != this->success.end(); ++_iter309)
      {
        xfer += oprot->writeString(_iter309->first);
        xfer += oprot->writeString(_iter309->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getTableProperties_presult::~AccumuloProxy_getTableProperties_presult() noexcept {
}


uint32_t AccumuloProxy_getTableProperties_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size310;
            ::apache::thrift::protocol::TType _ktype311;
            ::apache::thrift::protocol::TType _vtype312;
            xfer += iprot->readMapBegin(_ktype311, _vtype312, _size310);
            uint32_t _i314;
            for (_i314 = 0; _i314 < _size310; ++_i314)
            {
              std::string _key315;
              xfer += iprot->readString(_key315);
              std::string& _val316 = (*(this->success))[_key315];
              xfer += iprot->readString(_val316);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_importDirectory_args::~AccumuloProxy_importDirectory_args() noexcept {
}


uint32_t AccumuloProxy_importDirectory_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->importDir);
          this->__isset.importDir = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->failureDir);
          this->__isset.failureDir = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 5:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->setTime);
          this->__isset.setTime = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_importDirectory_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_importDirectory_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("importDir", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->importDir);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("failureDir", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString(this->failureDir);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setTime", ::apache::thrift::protocol::T_BOOL, 5);
  xfer += oprot->writeBool(this->setTime);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_importDirectory_pargs::~AccumuloProxy_importDirectory_pargs() noexcept {
}


uint32_t AccumuloProxy_importDirectory_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_importDirectory_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("importDir", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->importDir)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("failureDir", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString((*(this->failureDir)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setTime", ::apache::thrift::protocol::T_BOOL, 5);
  xfer += oprot->writeBool((*(this->setTime)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_importDirectory_result::~AccumuloProxy_importDirectory_result() noexcept {
}


uint32_t AccumuloProxy_importDirectory_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_importDirectory_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_importDirectory_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch4) {
    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch4.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_importDirectory_presult::~AccumuloProxy_importDirectory_presult() noexcept {
}


uint32_t AccumuloProxy_importDirectory_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_importTable_args::~AccumuloProxy_importTable_args() noexcept {
}


uint32_t AccumuloProxy_importTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->importDir);
          this->__isset.importDir = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_importTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_importTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("importDir", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->importDir);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_importTable_pargs::~AccumuloProxy_importTable_pargs() noexcept {
}


uint32_t AccumuloProxy_importTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_importTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("importDir", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->importDir)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_importTable_result::~AccumuloProxy_importTable_result() noexcept {
}


uint32_t AccumuloProxy_importTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_importTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_importTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_importTable_presult::~AccumuloProxy_importTable_presult() noexcept {
}


uint32_t AccumuloProxy_importTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listSplits_args::~AccumuloProxy_listSplits_args() noexcept {
}


uint32_t AccumuloProxy_listSplits_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->maxSplits);
          this->__isset.maxSplits = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listSplits_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listSplits_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("maxSplits", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(this->maxSplits);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listSplits_pargs::~AccumuloProxy_listSplits_pargs() noexcept {
}


uint32_t AccumuloProxy_listSplits_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listSplits_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("maxSplits", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32((*(this->maxSplits)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listSplits_result::~AccumuloProxy_listSplits_result() noexcept {
}


uint32_t AccumuloProxy_listSplits_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size317;
            ::apache::thrift::protocol::TType _etype320;
            xfer += iprot->readListBegin(_etype320, _size317);
            this->success.resize(_size317);
            uint32_t _i321;
            for (_i321 = 0; _i321 < _size317; ++_i321)
            {
              xfer += iprot->readBinary(this->success[_i321]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listSplits_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listSplits_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::vector<std::string> ::const_iterator _iter322;
      for (_iter322 = this->success.begin(); _iter322 != this->success.end(); ++_iter322)
      {
        xfer += oprot->writeBinary((*_iter322));
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listSplits_presult::~AccumuloProxy_listSplits_presult() noexcept {
}


uint32_t AccumuloProxy_listSplits_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size323;
            ::apache::thrift::protocol::TType _etype326;
            xfer += iprot->readListBegin(_etype326, _size323);
            (*(this->success)).resize(_size323);
            uint32_t _i327;
            for (_i327 = 0; _i327 < _size323; ++_i327)
            {
              xfer += iprot->readBinary((*(this->success))[_i327]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listTables_args::~AccumuloProxy_listTables_args() noexcept {
}


uint32_t AccumuloProxy_listTables_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listTables_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listTables_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listTables_pargs::~AccumuloProxy_listTables_pargs() noexcept {
}


uint32_t AccumuloProxy_listTables_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listTables_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listTables_result::~AccumuloProxy_listTables_result() noexcept {
}


uint32_t AccumuloProxy_listTables_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->success.clear();
            uint32_t _size328;
            ::apache::thrift::protocol::TType _etype331;
            xfer += iprot->readSetBegin(_etype331, _size328);
            uint32_t _i332;
            for (_i332 = 0; _i332 < _size328; ++_i332)
            {
              std::string _elem333;
              xfer += iprot->readString(_elem333);
              this->success.insert(_elem333);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listTables_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listTables_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_SET, 0);
    {
      xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::set<std::string> ::const_iterator _iter334;
      for (_iter334 = this->success.begin(); _iter334 != this->success.end(); ++_iter334)
      {
        xfer += oprot->writeString((*_iter334));
      }
      xfer += oprot->writeSetEnd();
    }
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listTables_presult::~AccumuloProxy_listTables_presult() noexcept {
}


uint32_t AccumuloProxy_listTables_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            (*(this->success)).clear();
            uint32_t _size335;
            ::apache::thrift::protocol::TType _etype338;
            xfer += iprot->readSetBegin(_etype338, _size335);
            uint32_t _i339;
            for (_i339 = 0; _i339 < _size335; ++_i339)
            {
              std::string _elem340;
              xfer += iprot->readString(_elem340);
              (*(this->success)).insert(_elem340);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listIterators_args::~AccumuloProxy_listIterators_args() noexcept {
}


uint32_t AccumuloProxy_listIterators_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listIterators_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listIterators_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listIterators_pargs::~AccumuloProxy_listIterators_pargs() noexcept {
}


uint32_t AccumuloProxy_listIterators_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listIterators_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listIterators_result::~AccumuloProxy_listIterators_result() noexcept {
}


uint32_t AccumuloProxy_listIterators_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size341;
            ::apache::thrift::protocol::TType _ktype342;
            ::apache::thrift::protocol::TType _vtype343;
            xfer += iprot->readMapBegin(_ktype342, _vtype343, _size341);
            uint32_t _i345;
            for (_i345 = 0; _i345 < _size341; ++_i345)
            {
              std::string _key346;
              xfer += iprot->readString(_key346);
              std::set<IteratorScope::type> & _val347 = this->success[_key346];
              {
                _val347.clear();
                uint32_t _size348;
                ::apache::thrift::protocol::TType _etype351;
                xfer += iprot->readSetBegin(_etype351, _size348);
                uint32_t _i352;
                for (_i352 = 0; _i352 < _size348; ++_i352)
                {
                  IteratorScope::type _elem353;
                  int32_t ecast354;
                  xfer += iprot->readI32(ecast354);
                  _elem353 = static_cast<IteratorScope::type>(ecast354);
                  _val347.insert(_elem353);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listIterators_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listIterators_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::set<IteratorScope::type> > ::const_iterator _iter355;
      for (_iter355 = this->success.begin(); _iter355 != this->success.end(); ++_iter355)
      {
        xfer += oprot->writeString(_iter355->first);
        {
          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(_iter355->second.size()));
          std::set<IteratorScope::type> ::const_iterator _iter356;
          for (_iter356 = _iter355->second.begin(); _iter356 != _iter355->second.end(); ++_iter356)
          {
            xfer += oprot->writeI32(static_cast<int32_t>((*_iter356)));
          }
          xfer += oprot->writeSetEnd();
        }
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listIterators_presult::~AccumuloProxy_listIterators_presult() noexcept {
}


uint32_t AccumuloProxy_listIterators_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size357;
            ::apache::thrift::protocol::TType _ktype358;
            ::apache::thrift::protocol::TType _vtype359;
            xfer += iprot->readMapBegin(_ktype358, _vtype359, _size357);
            uint32_t _i361;
            for (_i361 = 0; _i361 < _size357; ++_i361)
            {
              std::string _key362;
              xfer += iprot->readString(_key362);
              std::set<IteratorScope::type> & _val363 = (*(this->success))[_key362];
              {
                _val363.clear();
                uint32_t _size364;
                ::apache::thrift::protocol::TType _etype367;
                xfer += iprot->readSetBegin(_etype367, _size364);
                uint32_t _i368;
                for (_i368 = 0; _i368 < _size364; ++_i368)
                {
                  IteratorScope::type _elem369;
                  int32_t ecast370;
                  xfer += iprot->readI32(ecast370);
                  _elem369 = static_cast<IteratorScope::type>(ecast370);
                  _val363.insert(_elem369);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listConstraints_args::~AccumuloProxy_listConstraints_args() noexcept {
}


uint32_t AccumuloProxy_listConstraints_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listConstraints_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listConstraints_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listConstraints_pargs::~AccumuloProxy_listConstraints_pargs() noexcept {
}


uint32_t AccumuloProxy_listConstraints_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listConstraints_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listConstraints_result::~AccumuloProxy_listConstraints_result() noexcept {
}


uint32_t AccumuloProxy_listConstraints_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size371;
            ::apache::thrift::protocol::TType _ktype372;
            ::apache::thrift::protocol::TType _vtype373;
            xfer += iprot->readMapBegin(_ktype372, _vtype373, _size371);
            uint32_t _i375;
            for (_i375 = 0; _i375 < _size371; ++_i375)
            {
              std::string _key376;
              xfer += iprot->readString(_key376);
              int32_t& _val377 = this->success[_key376];
              xfer += iprot->readI32(_val377);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listConstraints_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listConstraints_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, int32_t> ::const_iterator _iter378;
      for (_iter378 = this->success.begin(); _iter378 != this->success.end(); ++_iter378)
      {
        xfer += oprot->writeString(_iter378->first);
        xfer += oprot->writeI32(_iter378->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listConstraints_presult::~AccumuloProxy_listConstraints_presult() noexcept {
}


uint32_t AccumuloProxy_listConstraints_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size379;
            ::apache::thrift::protocol::TType _ktype380;
            ::apache::thrift::protocol::TType _vtype381;
            xfer += iprot->readMapBegin(_ktype380, _vtype381, _size379);
            uint32_t _i383;
            for (_i383 = 0; _i383 < _size379; ++_i383)
            {
              std::string _key384;
              xfer += iprot->readString(_key384);
              int32_t& _val385 = (*(this->success))[_key384];
              xfer += iprot->readI32(_val385);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_mergeTablets_args::~AccumuloProxy_mergeTablets_args() noexcept {
}


uint32_t AccumuloProxy_mergeTablets_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->startRow);
          this->__isset.startRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->endRow);
          this->__isset.endRow = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_mergeTablets_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_mergeTablets_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->startRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary(this->endRow);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_mergeTablets_pargs::~AccumuloProxy_mergeTablets_pargs() noexcept {
}


uint32_t AccumuloProxy_mergeTablets_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_mergeTablets_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("startRow", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->startRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("endRow", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeBinary((*(this->endRow)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_mergeTablets_result::~AccumuloProxy_mergeTablets_result() noexcept {
}


uint32_t AccumuloProxy_mergeTablets_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_mergeTablets_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_mergeTablets_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_mergeTablets_presult::~AccumuloProxy_mergeTablets_presult() noexcept {
}


uint32_t AccumuloProxy_mergeTablets_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_offlineTable_args::~AccumuloProxy_offlineTable_args() noexcept {
}


uint32_t AccumuloProxy_offlineTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->wait);
          this->__isset.wait = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_offlineTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_offlineTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 3);
  xfer += oprot->writeBool(this->wait);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_offlineTable_pargs::~AccumuloProxy_offlineTable_pargs() noexcept {
}


uint32_t AccumuloProxy_offlineTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_offlineTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 3);
  xfer += oprot->writeBool((*(this->wait)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_offlineTable_result::~AccumuloProxy_offlineTable_result() noexcept {
}


uint32_t AccumuloProxy_offlineTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_offlineTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_offlineTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_offlineTable_presult::~AccumuloProxy_offlineTable_presult() noexcept {
}


uint32_t AccumuloProxy_offlineTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_onlineTable_args::~AccumuloProxy_onlineTable_args() noexcept {
}


uint32_t AccumuloProxy_onlineTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->wait);
          this->__isset.wait = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_onlineTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_onlineTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 3);
  xfer += oprot->writeBool(this->wait);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_onlineTable_pargs::~AccumuloProxy_onlineTable_pargs() noexcept {
}


uint32_t AccumuloProxy_onlineTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_onlineTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("wait", ::apache::thrift::protocol::T_BOOL, 3);
  xfer += oprot->writeBool((*(this->wait)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_onlineTable_result::~AccumuloProxy_onlineTable_result() noexcept {
}


uint32_t AccumuloProxy_onlineTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_onlineTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_onlineTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_onlineTable_presult::~AccumuloProxy_onlineTable_presult() noexcept {
}


uint32_t AccumuloProxy_onlineTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeConstraint_args::~AccumuloProxy_removeConstraint_args() noexcept {
}


uint32_t AccumuloProxy_removeConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->constraint);
          this->__isset.constraint = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeConstraint_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("constraint", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(this->constraint);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeConstraint_pargs::~AccumuloProxy_removeConstraint_pargs() noexcept {
}


uint32_t AccumuloProxy_removeConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeConstraint_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("constraint", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32((*(this->constraint)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeConstraint_result::~AccumuloProxy_removeConstraint_result() noexcept {
}


uint32_t AccumuloProxy_removeConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeConstraint_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeConstraint_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeConstraint_presult::~AccumuloProxy_removeConstraint_presult() noexcept {
}


uint32_t AccumuloProxy_removeConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeIterator_args::~AccumuloProxy_removeIterator_args() noexcept {
}


uint32_t AccumuloProxy_removeIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->iterName);
          this->__isset.iterName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->scopes.clear();
            uint32_t _size386;
            ::apache::thrift::protocol::TType _etype389;
            xfer += iprot->readSetBegin(_etype389, _size386);
            uint32_t _i390;
            for (_i390 = 0; _i390 < _size386; ++_i390)
            {
              IteratorScope::type _elem391;
              int32_t ecast392;
              xfer += iprot->readI32(ecast392);
              _elem391 = static_cast<IteratorScope::type>(ecast392);
              this->scopes.insert(_elem391);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.scopes = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeIterator_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("iterName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->iterName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
    std::set<IteratorScope::type> ::const_iterator _iter393;
    for (_iter393 = this->scopes.begin(); _iter393 != this->scopes.end(); ++_iter393)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter393)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeIterator_pargs::~AccumuloProxy_removeIterator_pargs() noexcept {
}


uint32_t AccumuloProxy_removeIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeIterator_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("iterName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->iterName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
    std::set<IteratorScope::type> ::const_iterator _iter394;
    for (_iter394 = (*(this->scopes)).begin(); _iter394 != (*(this->scopes)).end(); ++_iter394)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter394)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeIterator_result::~AccumuloProxy_removeIterator_result() noexcept {
}


uint32_t AccumuloProxy_removeIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeIterator_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeIterator_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeIterator_presult::~AccumuloProxy_removeIterator_presult() noexcept {
}


uint32_t AccumuloProxy_removeIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeTableProperty_args::~AccumuloProxy_removeTableProperty_args() noexcept {
}


uint32_t AccumuloProxy_removeTableProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->property);
          this->__isset.property = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeTableProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeTableProperty_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->property);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeTableProperty_pargs::~AccumuloProxy_removeTableProperty_pargs() noexcept {
}


uint32_t AccumuloProxy_removeTableProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeTableProperty_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->property)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeTableProperty_result::~AccumuloProxy_removeTableProperty_result() noexcept {
}


uint32_t AccumuloProxy_removeTableProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeTableProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeTableProperty_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeTableProperty_presult::~AccumuloProxy_removeTableProperty_presult() noexcept {
}


uint32_t AccumuloProxy_removeTableProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_renameTable_args::~AccumuloProxy_renameTable_args() noexcept {
}


uint32_t AccumuloProxy_renameTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->oldTableName);
          this->__isset.oldTableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->newTableName);
          this->__isset.newTableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_renameTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_renameTable_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("oldTableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->oldTableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("newTableName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->newTableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_renameTable_pargs::~AccumuloProxy_renameTable_pargs() noexcept {
}


uint32_t AccumuloProxy_renameTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_renameTable_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("oldTableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->oldTableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("newTableName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->newTableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_renameTable_result::~AccumuloProxy_renameTable_result() noexcept {
}


uint32_t AccumuloProxy_renameTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_renameTable_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_renameTable_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch4) {
    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
    xfer += this->ouch4.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_renameTable_presult::~AccumuloProxy_renameTable_presult() noexcept {
}


uint32_t AccumuloProxy_renameTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_setLocalityGroups_args::~AccumuloProxy_setLocalityGroups_args() noexcept {
}


uint32_t AccumuloProxy_setLocalityGroups_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->groups.clear();
            uint32_t _size395;
            ::apache::thrift::protocol::TType _ktype396;
            ::apache::thrift::protocol::TType _vtype397;
            xfer += iprot->readMapBegin(_ktype396, _vtype397, _size395);
            uint32_t _i399;
            for (_i399 = 0; _i399 < _size395; ++_i399)
            {
              std::string _key400;
              xfer += iprot->readString(_key400);
              std::set<std::string> & _val401 = this->groups[_key400];
              {
                _val401.clear();
                uint32_t _size402;
                ::apache::thrift::protocol::TType _etype405;
                xfer += iprot->readSetBegin(_etype405, _size402);
                uint32_t _i406;
                for (_i406 = 0; _i406 < _size402; ++_i406)
                {
                  std::string _elem407;
                  xfer += iprot->readString(_elem407);
                  _val401.insert(_elem407);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.groups = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setLocalityGroups_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setLocalityGroups_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("groups", ::apache::thrift::protocol::T_MAP, 3);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->groups.size()));
    std::map<std::string, std::set<std::string> > ::const_iterator _iter408;
    for (_iter408 = this->groups.begin(); _iter408 != this->groups.end(); ++_iter408)
    {
      xfer += oprot->writeString(_iter408->first);
      {
        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter408->second.size()));
        std::set<std::string> ::const_iterator _iter409;
        for (_iter409 = _iter408->second.begin(); _iter409 != _iter408->second.end(); ++_iter409)
        {
          xfer += oprot->writeString((*_iter409));
        }
        xfer += oprot->writeSetEnd();
      }
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setLocalityGroups_pargs::~AccumuloProxy_setLocalityGroups_pargs() noexcept {
}


uint32_t AccumuloProxy_setLocalityGroups_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setLocalityGroups_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("groups", ::apache::thrift::protocol::T_MAP, 3);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>((*(this->groups)).size()));
    std::map<std::string, std::set<std::string> > ::const_iterator _iter410;
    for (_iter410 = (*(this->groups)).begin(); _iter410 != (*(this->groups)).end(); ++_iter410)
    {
      xfer += oprot->writeString(_iter410->first);
      {
        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter410->second.size()));
        std::set<std::string> ::const_iterator _iter411;
        for (_iter411 = _iter410->second.begin(); _iter411 != _iter410->second.end(); ++_iter411)
        {
          xfer += oprot->writeString((*_iter411));
        }
        xfer += oprot->writeSetEnd();
      }
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setLocalityGroups_result::~AccumuloProxy_setLocalityGroups_result() noexcept {
}


uint32_t AccumuloProxy_setLocalityGroups_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setLocalityGroups_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_setLocalityGroups_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setLocalityGroups_presult::~AccumuloProxy_setLocalityGroups_presult() noexcept {
}


uint32_t AccumuloProxy_setLocalityGroups_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_setTableProperty_args::~AccumuloProxy_setTableProperty_args() noexcept {
}


uint32_t AccumuloProxy_setTableProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->property);
          this->__isset.property = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->value);
          this->__isset.value = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setTableProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setTableProperty_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->property);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString(this->value);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setTableProperty_pargs::~AccumuloProxy_setTableProperty_pargs() noexcept {
}


uint32_t AccumuloProxy_setTableProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setTableProperty_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->property)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString((*(this->value)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setTableProperty_result::~AccumuloProxy_setTableProperty_result() noexcept {
}


uint32_t AccumuloProxy_setTableProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setTableProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_setTableProperty_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setTableProperty_presult::~AccumuloProxy_setTableProperty_presult() noexcept {
}


uint32_t AccumuloProxy_setTableProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_splitRangeByTablets_args::~AccumuloProxy_splitRangeByTablets_args() noexcept {
}


uint32_t AccumuloProxy_splitRangeByTablets_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->range.read(iprot);
          this->__isset.range = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->maxSplits);
          this->__isset.maxSplits = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_splitRangeByTablets_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_splitRangeByTablets_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("range", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->range.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("maxSplits", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(this->maxSplits);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_splitRangeByTablets_pargs::~AccumuloProxy_splitRangeByTablets_pargs() noexcept {
}


uint32_t AccumuloProxy_splitRangeByTablets_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_splitRangeByTablets_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("range", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->range)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("maxSplits", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32((*(this->maxSplits)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_splitRangeByTablets_result::~AccumuloProxy_splitRangeByTablets_result() noexcept {
}


uint32_t AccumuloProxy_splitRangeByTablets_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->success.clear();
            uint32_t _size412;
            ::apache::thrift::protocol::TType _etype415;
            xfer += iprot->readSetBegin(_etype415, _size412);
            uint32_t _i416;
            for (_i416 = 0; _i416 < _size412; ++_i416)
            {
              Range _elem417;
              xfer += _elem417.read(iprot);
              this->success.insert(_elem417);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_splitRangeByTablets_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_splitRangeByTablets_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_SET, 0);
    {
      xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
      std::set<Range> ::const_iterator _iter418;
      for (_iter418 = this->success.begin(); _iter418 != this->success.end(); ++_iter418)
      {
        xfer += (*_iter418).write(oprot);
      }
      xfer += oprot->writeSetEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_splitRangeByTablets_presult::~AccumuloProxy_splitRangeByTablets_presult() noexcept {
}


uint32_t AccumuloProxy_splitRangeByTablets_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            (*(this->success)).clear();
            uint32_t _size419;
            ::apache::thrift::protocol::TType _etype422;
            xfer += iprot->readSetBegin(_etype422, _size419);
            uint32_t _i423;
            for (_i423 = 0; _i423 < _size419; ++_i423)
            {
              Range _elem424;
              xfer += _elem424.read(iprot);
              (*(this->success)).insert(_elem424);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_tableExists_args::~AccumuloProxy_tableExists_args() noexcept {
}


uint32_t AccumuloProxy_tableExists_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_tableExists_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_tableExists_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_tableExists_pargs::~AccumuloProxy_tableExists_pargs() noexcept {
}


uint32_t AccumuloProxy_tableExists_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_tableExists_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_tableExists_result::~AccumuloProxy_tableExists_result() noexcept {
}


uint32_t AccumuloProxy_tableExists_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_tableExists_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_tableExists_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_tableExists_presult::~AccumuloProxy_tableExists_presult() noexcept {
}


uint32_t AccumuloProxy_tableExists_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_tableIdMap_args::~AccumuloProxy_tableIdMap_args() noexcept {
}


uint32_t AccumuloProxy_tableIdMap_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_tableIdMap_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_tableIdMap_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_tableIdMap_pargs::~AccumuloProxy_tableIdMap_pargs() noexcept {
}


uint32_t AccumuloProxy_tableIdMap_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_tableIdMap_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_tableIdMap_result::~AccumuloProxy_tableIdMap_result() noexcept {
}


uint32_t AccumuloProxy_tableIdMap_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size425;
            ::apache::thrift::protocol::TType _ktype426;
            ::apache::thrift::protocol::TType _vtype427;
            xfer += iprot->readMapBegin(_ktype426, _vtype427, _size425);
            uint32_t _i429;
            for (_i429 = 0; _i429 < _size425; ++_i429)
            {
              std::string _key430;
              xfer += iprot->readString(_key430);
              std::string& _val431 = this->success[_key430];
              xfer += iprot->readString(_val431);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_tableIdMap_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_tableIdMap_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::string> ::const_iterator _iter432;
      for (_iter432 = this->success.begin(); _iter432 != this->success.end(); ++_iter432)
      {
        xfer += oprot->writeString(_iter432->first);
        xfer += oprot->writeString(_iter432->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_tableIdMap_presult::~AccumuloProxy_tableIdMap_presult() noexcept {
}


uint32_t AccumuloProxy_tableIdMap_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size433;
            ::apache::thrift::protocol::TType _ktype434;
            ::apache::thrift::protocol::TType _vtype435;
            xfer += iprot->readMapBegin(_ktype434, _vtype435, _size433);
            uint32_t _i437;
            for (_i437 = 0; _i437 < _size433; ++_i437)
            {
              std::string _key438;
              xfer += iprot->readString(_key438);
              std::string& _val439 = (*(this->success))[_key438];
              xfer += iprot->readString(_val439);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_testTableClassLoad_args::~AccumuloProxy_testTableClassLoad_args() noexcept {
}


uint32_t AccumuloProxy_testTableClassLoad_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->className);
          this->__isset.className = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->asTypeName);
          this->__isset.asTypeName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_testTableClassLoad_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_testTableClassLoad_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->className);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString(this->asTypeName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testTableClassLoad_pargs::~AccumuloProxy_testTableClassLoad_pargs() noexcept {
}


uint32_t AccumuloProxy_testTableClassLoad_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_testTableClassLoad_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->className)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString((*(this->asTypeName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testTableClassLoad_result::~AccumuloProxy_testTableClassLoad_result() noexcept {
}


uint32_t AccumuloProxy_testTableClassLoad_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_testTableClassLoad_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_testTableClassLoad_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testTableClassLoad_presult::~AccumuloProxy_testTableClassLoad_presult() noexcept {
}


uint32_t AccumuloProxy_testTableClassLoad_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_pingTabletServer_args::~AccumuloProxy_pingTabletServer_args() noexcept {
}


uint32_t AccumuloProxy_pingTabletServer_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tserver);
          this->__isset.tserver = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_pingTabletServer_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_pingTabletServer_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tserver", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tserver);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_pingTabletServer_pargs::~AccumuloProxy_pingTabletServer_pargs() noexcept {
}


uint32_t AccumuloProxy_pingTabletServer_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_pingTabletServer_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tserver", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tserver)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_pingTabletServer_result::~AccumuloProxy_pingTabletServer_result() noexcept {
}


uint32_t AccumuloProxy_pingTabletServer_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_pingTabletServer_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_pingTabletServer_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_pingTabletServer_presult::~AccumuloProxy_pingTabletServer_presult() noexcept {
}


uint32_t AccumuloProxy_pingTabletServer_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getActiveScans_args::~AccumuloProxy_getActiveScans_args() noexcept {
}


uint32_t AccumuloProxy_getActiveScans_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tserver);
          this->__isset.tserver = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getActiveScans_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getActiveScans_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tserver", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tserver);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getActiveScans_pargs::~AccumuloProxy_getActiveScans_pargs() noexcept {
}


uint32_t AccumuloProxy_getActiveScans_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getActiveScans_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tserver", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tserver)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getActiveScans_result::~AccumuloProxy_getActiveScans_result() noexcept {
}


uint32_t AccumuloProxy_getActiveScans_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size440;
            ::apache::thrift::protocol::TType _etype443;
            xfer += iprot->readListBegin(_etype443, _size440);
            this->success.resize(_size440);
            uint32_t _i444;
            for (_i444 = 0; _i444 < _size440; ++_i444)
            {
              xfer += this->success[_i444].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getActiveScans_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getActiveScans_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
      std::vector<ActiveScan> ::const_iterator _iter445;
      for (_iter445 = this->success.begin(); _iter445 != this->success.end(); ++_iter445)
      {
        xfer += (*_iter445).write(oprot);
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getActiveScans_presult::~AccumuloProxy_getActiveScans_presult() noexcept {
}


uint32_t AccumuloProxy_getActiveScans_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size446;
            ::apache::thrift::protocol::TType _etype449;
            xfer += iprot->readListBegin(_etype449, _size446);
            (*(this->success)).resize(_size446);
            uint32_t _i450;
            for (_i450 = 0; _i450 < _size446; ++_i450)
            {
              xfer += (*(this->success))[_i450].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getActiveCompactions_args::~AccumuloProxy_getActiveCompactions_args() noexcept {
}


uint32_t AccumuloProxy_getActiveCompactions_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tserver);
          this->__isset.tserver = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getActiveCompactions_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getActiveCompactions_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tserver", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tserver);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getActiveCompactions_pargs::~AccumuloProxy_getActiveCompactions_pargs() noexcept {
}


uint32_t AccumuloProxy_getActiveCompactions_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getActiveCompactions_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tserver", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tserver)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getActiveCompactions_result::~AccumuloProxy_getActiveCompactions_result() noexcept {
}


uint32_t AccumuloProxy_getActiveCompactions_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size451;
            ::apache::thrift::protocol::TType _etype454;
            xfer += iprot->readListBegin(_etype454, _size451);
            this->success.resize(_size451);
            uint32_t _i455;
            for (_i455 = 0; _i455 < _size451; ++_i455)
            {
              xfer += this->success[_i455].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getActiveCompactions_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getActiveCompactions_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
      std::vector<ActiveCompaction> ::const_iterator _iter456;
      for (_iter456 = this->success.begin(); _iter456 != this->success.end(); ++_iter456)
      {
        xfer += (*_iter456).write(oprot);
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getActiveCompactions_presult::~AccumuloProxy_getActiveCompactions_presult() noexcept {
}


uint32_t AccumuloProxy_getActiveCompactions_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size457;
            ::apache::thrift::protocol::TType _etype460;
            xfer += iprot->readListBegin(_etype460, _size457);
            (*(this->success)).resize(_size457);
            uint32_t _i461;
            for (_i461 = 0; _i461 < _size457; ++_i461)
            {
              xfer += (*(this->success))[_i461].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getSiteConfiguration_args::~AccumuloProxy_getSiteConfiguration_args() noexcept {
}


uint32_t AccumuloProxy_getSiteConfiguration_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getSiteConfiguration_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getSiteConfiguration_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getSiteConfiguration_pargs::~AccumuloProxy_getSiteConfiguration_pargs() noexcept {
}


uint32_t AccumuloProxy_getSiteConfiguration_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getSiteConfiguration_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getSiteConfiguration_result::~AccumuloProxy_getSiteConfiguration_result() noexcept {
}


uint32_t AccumuloProxy_getSiteConfiguration_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size462;
            ::apache::thrift::protocol::TType _ktype463;
            ::apache::thrift::protocol::TType _vtype464;
            xfer += iprot->readMapBegin(_ktype463, _vtype464, _size462);
            uint32_t _i466;
            for (_i466 = 0; _i466 < _size462; ++_i466)
            {
              std::string _key467;
              xfer += iprot->readString(_key467);
              std::string& _val468 = this->success[_key467];
              xfer += iprot->readString(_val468);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getSiteConfiguration_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getSiteConfiguration_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::string> ::const_iterator _iter469;
      for (_iter469 = this->success.begin(); _iter469 != this->success.end(); ++_iter469)
      {
        xfer += oprot->writeString(_iter469->first);
        xfer += oprot->writeString(_iter469->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getSiteConfiguration_presult::~AccumuloProxy_getSiteConfiguration_presult() noexcept {
}


uint32_t AccumuloProxy_getSiteConfiguration_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size470;
            ::apache::thrift::protocol::TType _ktype471;
            ::apache::thrift::protocol::TType _vtype472;
            xfer += iprot->readMapBegin(_ktype471, _vtype472, _size470);
            uint32_t _i474;
            for (_i474 = 0; _i474 < _size470; ++_i474)
            {
              std::string _key475;
              xfer += iprot->readString(_key475);
              std::string& _val476 = (*(this->success))[_key475];
              xfer += iprot->readString(_val476);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getSystemConfiguration_args::~AccumuloProxy_getSystemConfiguration_args() noexcept {
}


uint32_t AccumuloProxy_getSystemConfiguration_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getSystemConfiguration_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getSystemConfiguration_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getSystemConfiguration_pargs::~AccumuloProxy_getSystemConfiguration_pargs() noexcept {
}


uint32_t AccumuloProxy_getSystemConfiguration_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getSystemConfiguration_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getSystemConfiguration_result::~AccumuloProxy_getSystemConfiguration_result() noexcept {
}


uint32_t AccumuloProxy_getSystemConfiguration_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size477;
            ::apache::thrift::protocol::TType _ktype478;
            ::apache::thrift::protocol::TType _vtype479;
            xfer += iprot->readMapBegin(_ktype478, _vtype479, _size477);
            uint32_t _i481;
            for (_i481 = 0; _i481 < _size477; ++_i481)
            {
              std::string _key482;
              xfer += iprot->readString(_key482);
              std::string& _val483 = this->success[_key482];
              xfer += iprot->readString(_val483);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getSystemConfiguration_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getSystemConfiguration_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::string> ::const_iterator _iter484;
      for (_iter484 = this->success.begin(); _iter484 != this->success.end(); ++_iter484)
      {
        xfer += oprot->writeString(_iter484->first);
        xfer += oprot->writeString(_iter484->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getSystemConfiguration_presult::~AccumuloProxy_getSystemConfiguration_presult() noexcept {
}


uint32_t AccumuloProxy_getSystemConfiguration_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size485;
            ::apache::thrift::protocol::TType _ktype486;
            ::apache::thrift::protocol::TType _vtype487;
            xfer += iprot->readMapBegin(_ktype486, _vtype487, _size485);
            uint32_t _i489;
            for (_i489 = 0; _i489 < _size485; ++_i489)
            {
              std::string _key490;
              xfer += iprot->readString(_key490);
              std::string& _val491 = (*(this->success))[_key490];
              xfer += iprot->readString(_val491);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getTabletServers_args::~AccumuloProxy_getTabletServers_args() noexcept {
}


uint32_t AccumuloProxy_getTabletServers_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getTabletServers_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getTabletServers_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getTabletServers_pargs::~AccumuloProxy_getTabletServers_pargs() noexcept {
}


uint32_t AccumuloProxy_getTabletServers_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getTabletServers_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getTabletServers_result::~AccumuloProxy_getTabletServers_result() noexcept {
}


uint32_t AccumuloProxy_getTabletServers_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size492;
            ::apache::thrift::protocol::TType _etype495;
            xfer += iprot->readListBegin(_etype495, _size492);
            this->success.resize(_size492);
            uint32_t _i496;
            for (_i496 = 0; _i496 < _size492; ++_i496)
            {
              xfer += iprot->readString(this->success[_i496]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getTabletServers_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getTabletServers_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::vector<std::string> ::const_iterator _iter497;
      for (_iter497 = this->success.begin(); _iter497 != this->success.end(); ++_iter497)
      {
        xfer += oprot->writeString((*_iter497));
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getTabletServers_presult::~AccumuloProxy_getTabletServers_presult() noexcept {
}


uint32_t AccumuloProxy_getTabletServers_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size498;
            ::apache::thrift::protocol::TType _etype501;
            xfer += iprot->readListBegin(_etype501, _size498);
            (*(this->success)).resize(_size498);
            uint32_t _i502;
            for (_i502 = 0; _i502 < _size498; ++_i502)
            {
              xfer += iprot->readString((*(this->success))[_i502]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeProperty_args::~AccumuloProxy_removeProperty_args() noexcept {
}


uint32_t AccumuloProxy_removeProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->property);
          this->__isset.property = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeProperty_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->property);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeProperty_pargs::~AccumuloProxy_removeProperty_pargs() noexcept {
}


uint32_t AccumuloProxy_removeProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeProperty_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->property)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeProperty_result::~AccumuloProxy_removeProperty_result() noexcept {
}


uint32_t AccumuloProxy_removeProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeProperty_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeProperty_presult::~AccumuloProxy_removeProperty_presult() noexcept {
}


uint32_t AccumuloProxy_removeProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_setProperty_args::~AccumuloProxy_setProperty_args() noexcept {
}


uint32_t AccumuloProxy_setProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->property);
          this->__isset.property = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->value);
          this->__isset.value = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setProperty_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->property);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->value);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setProperty_pargs::~AccumuloProxy_setProperty_pargs() noexcept {
}


uint32_t AccumuloProxy_setProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setProperty_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->property)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->value)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setProperty_result::~AccumuloProxy_setProperty_result() noexcept {
}


uint32_t AccumuloProxy_setProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_setProperty_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setProperty_presult::~AccumuloProxy_setProperty_presult() noexcept {
}


uint32_t AccumuloProxy_setProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_testClassLoad_args::~AccumuloProxy_testClassLoad_args() noexcept {
}


uint32_t AccumuloProxy_testClassLoad_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->className);
          this->__isset.className = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->asTypeName);
          this->__isset.asTypeName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_testClassLoad_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_testClassLoad_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->className);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->asTypeName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testClassLoad_pargs::~AccumuloProxy_testClassLoad_pargs() noexcept {
}


uint32_t AccumuloProxy_testClassLoad_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_testClassLoad_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->className)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->asTypeName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testClassLoad_result::~AccumuloProxy_testClassLoad_result() noexcept {
}


uint32_t AccumuloProxy_testClassLoad_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_testClassLoad_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_testClassLoad_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testClassLoad_presult::~AccumuloProxy_testClassLoad_presult() noexcept {
}


uint32_t AccumuloProxy_testClassLoad_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_authenticateUser_args::~AccumuloProxy_authenticateUser_args() noexcept {
}


uint32_t AccumuloProxy_authenticateUser_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->properties.clear();
            uint32_t _size503;
            ::apache::thrift::protocol::TType _ktype504;
            ::apache::thrift::protocol::TType _vtype505;
            xfer += iprot->readMapBegin(_ktype504, _vtype505, _size503);
            uint32_t _i507;
            for (_i507 = 0; _i507 < _size503; ++_i507)
            {
              std::string _key508;
              xfer += iprot->readString(_key508);
              std::string& _val509 = this->properties[_key508];
              xfer += iprot->readString(_val509);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.properties = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_authenticateUser_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_authenticateUser_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("properties", ::apache::thrift::protocol::T_MAP, 3);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->properties.size()));
    std::map<std::string, std::string> ::const_iterator _iter510;
    for (_iter510 = this->properties.begin(); _iter510 != this->properties.end(); ++_iter510)
    {
      xfer += oprot->writeString(_iter510->first);
      xfer += oprot->writeString(_iter510->second);
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_authenticateUser_pargs::~AccumuloProxy_authenticateUser_pargs() noexcept {
}


uint32_t AccumuloProxy_authenticateUser_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_authenticateUser_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("properties", ::apache::thrift::protocol::T_MAP, 3);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->properties)).size()));
    std::map<std::string, std::string> ::const_iterator _iter511;
    for (_iter511 = (*(this->properties)).begin(); _iter511 != (*(this->properties)).end(); ++_iter511)
    {
      xfer += oprot->writeString(_iter511->first);
      xfer += oprot->writeString(_iter511->second);
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_authenticateUser_result::~AccumuloProxy_authenticateUser_result() noexcept {
}


uint32_t AccumuloProxy_authenticateUser_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_authenticateUser_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_authenticateUser_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_authenticateUser_presult::~AccumuloProxy_authenticateUser_presult() noexcept {
}


uint32_t AccumuloProxy_authenticateUser_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_changeUserAuthorizations_args::~AccumuloProxy_changeUserAuthorizations_args() noexcept {
}


uint32_t AccumuloProxy_changeUserAuthorizations_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->authorizations.clear();
            uint32_t _size512;
            ::apache::thrift::protocol::TType _etype515;
            xfer += iprot->readSetBegin(_etype515, _size512);
            uint32_t _i516;
            for (_i516 = 0; _i516 < _size512; ++_i516)
            {
              std::string _elem517;
              xfer += iprot->readBinary(_elem517);
              this->authorizations.insert(_elem517);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.authorizations = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_changeUserAuthorizations_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_changeUserAuthorizations_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 3);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->authorizations.size()));
    std::set<std::string> ::const_iterator _iter518;
    for (_iter518 = this->authorizations.begin(); _iter518 != this->authorizations.end(); ++_iter518)
    {
      xfer += oprot->writeBinary((*_iter518));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_changeUserAuthorizations_pargs::~AccumuloProxy_changeUserAuthorizations_pargs() noexcept {
}


uint32_t AccumuloProxy_changeUserAuthorizations_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_changeUserAuthorizations_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 3);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->authorizations)).size()));
    std::set<std::string> ::const_iterator _iter519;
    for (_iter519 = (*(this->authorizations)).begin(); _iter519 != (*(this->authorizations)).end(); ++_iter519)
    {
      xfer += oprot->writeBinary((*_iter519));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_changeUserAuthorizations_result::~AccumuloProxy_changeUserAuthorizations_result() noexcept {
}


uint32_t AccumuloProxy_changeUserAuthorizations_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_changeUserAuthorizations_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_changeUserAuthorizations_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_changeUserAuthorizations_presult::~AccumuloProxy_changeUserAuthorizations_presult() noexcept {
}


uint32_t AccumuloProxy_changeUserAuthorizations_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_changeLocalUserPassword_args::~AccumuloProxy_changeLocalUserPassword_args() noexcept {
}


uint32_t AccumuloProxy_changeLocalUserPassword_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->password);
          this->__isset.password = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_changeLocalUserPassword_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_changeLocalUserPassword_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("password", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->password);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_changeLocalUserPassword_pargs::~AccumuloProxy_changeLocalUserPassword_pargs() noexcept {
}


uint32_t AccumuloProxy_changeLocalUserPassword_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_changeLocalUserPassword_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("password", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->password)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_changeLocalUserPassword_result::~AccumuloProxy_changeLocalUserPassword_result() noexcept {
}


uint32_t AccumuloProxy_changeLocalUserPassword_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_changeLocalUserPassword_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_changeLocalUserPassword_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_changeLocalUserPassword_presult::~AccumuloProxy_changeLocalUserPassword_presult() noexcept {
}


uint32_t AccumuloProxy_changeLocalUserPassword_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createLocalUser_args::~AccumuloProxy_createLocalUser_args() noexcept {
}


uint32_t AccumuloProxy_createLocalUser_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->password);
          this->__isset.password = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createLocalUser_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createLocalUser_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("password", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->password);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createLocalUser_pargs::~AccumuloProxy_createLocalUser_pargs() noexcept {
}


uint32_t AccumuloProxy_createLocalUser_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createLocalUser_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("password", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->password)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createLocalUser_result::~AccumuloProxy_createLocalUser_result() noexcept {
}


uint32_t AccumuloProxy_createLocalUser_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createLocalUser_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createLocalUser_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createLocalUser_presult::~AccumuloProxy_createLocalUser_presult() noexcept {
}


uint32_t AccumuloProxy_createLocalUser_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_dropLocalUser_args::~AccumuloProxy_dropLocalUser_args() noexcept {
}


uint32_t AccumuloProxy_dropLocalUser_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_dropLocalUser_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_dropLocalUser_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_dropLocalUser_pargs::~AccumuloProxy_dropLocalUser_pargs() noexcept {
}


uint32_t AccumuloProxy_dropLocalUser_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_dropLocalUser_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_dropLocalUser_result::~AccumuloProxy_dropLocalUser_result() noexcept {
}


uint32_t AccumuloProxy_dropLocalUser_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_dropLocalUser_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_dropLocalUser_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_dropLocalUser_presult::~AccumuloProxy_dropLocalUser_presult() noexcept {
}


uint32_t AccumuloProxy_dropLocalUser_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getUserAuthorizations_args::~AccumuloProxy_getUserAuthorizations_args() noexcept {
}


uint32_t AccumuloProxy_getUserAuthorizations_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getUserAuthorizations_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getUserAuthorizations_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getUserAuthorizations_pargs::~AccumuloProxy_getUserAuthorizations_pargs() noexcept {
}


uint32_t AccumuloProxy_getUserAuthorizations_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getUserAuthorizations_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getUserAuthorizations_result::~AccumuloProxy_getUserAuthorizations_result() noexcept {
}


uint32_t AccumuloProxy_getUserAuthorizations_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size520;
            ::apache::thrift::protocol::TType _etype523;
            xfer += iprot->readListBegin(_etype523, _size520);
            this->success.resize(_size520);
            uint32_t _i524;
            for (_i524 = 0; _i524 < _size520; ++_i524)
            {
              xfer += iprot->readBinary(this->success[_i524]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getUserAuthorizations_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getUserAuthorizations_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::vector<std::string> ::const_iterator _iter525;
      for (_iter525 = this->success.begin(); _iter525 != this->success.end(); ++_iter525)
      {
        xfer += oprot->writeBinary((*_iter525));
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getUserAuthorizations_presult::~AccumuloProxy_getUserAuthorizations_presult() noexcept {
}


uint32_t AccumuloProxy_getUserAuthorizations_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size526;
            ::apache::thrift::protocol::TType _etype529;
            xfer += iprot->readListBegin(_etype529, _size526);
            (*(this->success)).resize(_size526);
            uint32_t _i530;
            for (_i530 = 0; _i530 < _size526; ++_i530)
            {
              xfer += iprot->readBinary((*(this->success))[_i530]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_grantSystemPermission_args::~AccumuloProxy_grantSystemPermission_args() noexcept {
}


uint32_t AccumuloProxy_grantSystemPermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast531;
          xfer += iprot->readI32(ecast531);
          this->perm = static_cast<SystemPermission::type>(ecast531);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_grantSystemPermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_grantSystemPermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantSystemPermission_pargs::~AccumuloProxy_grantSystemPermission_pargs() noexcept {
}


uint32_t AccumuloProxy_grantSystemPermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_grantSystemPermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantSystemPermission_result::~AccumuloProxy_grantSystemPermission_result() noexcept {
}


uint32_t AccumuloProxy_grantSystemPermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_grantSystemPermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_grantSystemPermission_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantSystemPermission_presult::~AccumuloProxy_grantSystemPermission_presult() noexcept {
}


uint32_t AccumuloProxy_grantSystemPermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_grantTablePermission_args::~AccumuloProxy_grantTablePermission_args() noexcept {
}


uint32_t AccumuloProxy_grantTablePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->table);
          this->__isset.table = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast532;
          xfer += iprot->readI32(ecast532);
          this->perm = static_cast<TablePermission::type>(ecast532);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_grantTablePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_grantTablePermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("table", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->table);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantTablePermission_pargs::~AccumuloProxy_grantTablePermission_pargs() noexcept {
}


uint32_t AccumuloProxy_grantTablePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_grantTablePermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("table", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->table)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantTablePermission_result::~AccumuloProxy_grantTablePermission_result() noexcept {
}


uint32_t AccumuloProxy_grantTablePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_grantTablePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_grantTablePermission_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantTablePermission_presult::~AccumuloProxy_grantTablePermission_presult() noexcept {
}


uint32_t AccumuloProxy_grantTablePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_hasSystemPermission_args::~AccumuloProxy_hasSystemPermission_args() noexcept {
}


uint32_t AccumuloProxy_hasSystemPermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast533;
          xfer += iprot->readI32(ecast533);
          this->perm = static_cast<SystemPermission::type>(ecast533);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasSystemPermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasSystemPermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasSystemPermission_pargs::~AccumuloProxy_hasSystemPermission_pargs() noexcept {
}


uint32_t AccumuloProxy_hasSystemPermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasSystemPermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasSystemPermission_result::~AccumuloProxy_hasSystemPermission_result() noexcept {
}


uint32_t AccumuloProxy_hasSystemPermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasSystemPermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_hasSystemPermission_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasSystemPermission_presult::~AccumuloProxy_hasSystemPermission_presult() noexcept {
}


uint32_t AccumuloProxy_hasSystemPermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_hasTablePermission_args::~AccumuloProxy_hasTablePermission_args() noexcept {
}


uint32_t AccumuloProxy_hasTablePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->table);
          this->__isset.table = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast534;
          xfer += iprot->readI32(ecast534);
          this->perm = static_cast<TablePermission::type>(ecast534);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasTablePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasTablePermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("table", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->table);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasTablePermission_pargs::~AccumuloProxy_hasTablePermission_pargs() noexcept {
}


uint32_t AccumuloProxy_hasTablePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasTablePermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("table", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->table)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasTablePermission_result::~AccumuloProxy_hasTablePermission_result() noexcept {
}


uint32_t AccumuloProxy_hasTablePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasTablePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_hasTablePermission_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasTablePermission_presult::~AccumuloProxy_hasTablePermission_presult() noexcept {
}


uint32_t AccumuloProxy_hasTablePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listLocalUsers_args::~AccumuloProxy_listLocalUsers_args() noexcept {
}


uint32_t AccumuloProxy_listLocalUsers_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listLocalUsers_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listLocalUsers_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listLocalUsers_pargs::~AccumuloProxy_listLocalUsers_pargs() noexcept {
}


uint32_t AccumuloProxy_listLocalUsers_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listLocalUsers_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listLocalUsers_result::~AccumuloProxy_listLocalUsers_result() noexcept {
}


uint32_t AccumuloProxy_listLocalUsers_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->success.clear();
            uint32_t _size535;
            ::apache::thrift::protocol::TType _etype538;
            xfer += iprot->readSetBegin(_etype538, _size535);
            uint32_t _i539;
            for (_i539 = 0; _i539 < _size535; ++_i539)
            {
              std::string _elem540;
              xfer += iprot->readString(_elem540);
              this->success.insert(_elem540);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listLocalUsers_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listLocalUsers_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_SET, 0);
    {
      xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::set<std::string> ::const_iterator _iter541;
      for (_iter541 = this->success.begin(); _iter541 != this->success.end(); ++_iter541)
      {
        xfer += oprot->writeString((*_iter541));
      }
      xfer += oprot->writeSetEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listLocalUsers_presult::~AccumuloProxy_listLocalUsers_presult() noexcept {
}


uint32_t AccumuloProxy_listLocalUsers_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            (*(this->success)).clear();
            uint32_t _size542;
            ::apache::thrift::protocol::TType _etype545;
            xfer += iprot->readSetBegin(_etype545, _size542);
            uint32_t _i546;
            for (_i546 = 0; _i546 < _size542; ++_i546)
            {
              std::string _elem547;
              xfer += iprot->readString(_elem547);
              (*(this->success)).insert(_elem547);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_revokeSystemPermission_args::~AccumuloProxy_revokeSystemPermission_args() noexcept {
}


uint32_t AccumuloProxy_revokeSystemPermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast548;
          xfer += iprot->readI32(ecast548);
          this->perm = static_cast<SystemPermission::type>(ecast548);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_revokeSystemPermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_revokeSystemPermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeSystemPermission_pargs::~AccumuloProxy_revokeSystemPermission_pargs() noexcept {
}


uint32_t AccumuloProxy_revokeSystemPermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_revokeSystemPermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeSystemPermission_result::~AccumuloProxy_revokeSystemPermission_result() noexcept {
}


uint32_t AccumuloProxy_revokeSystemPermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_revokeSystemPermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_revokeSystemPermission_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeSystemPermission_presult::~AccumuloProxy_revokeSystemPermission_presult() noexcept {
}


uint32_t AccumuloProxy_revokeSystemPermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_revokeTablePermission_args::~AccumuloProxy_revokeTablePermission_args() noexcept {
}


uint32_t AccumuloProxy_revokeTablePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->table);
          this->__isset.table = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast549;
          xfer += iprot->readI32(ecast549);
          this->perm = static_cast<TablePermission::type>(ecast549);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_revokeTablePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_revokeTablePermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("table", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->table);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeTablePermission_pargs::~AccumuloProxy_revokeTablePermission_pargs() noexcept {
}


uint32_t AccumuloProxy_revokeTablePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_revokeTablePermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("table", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->table)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeTablePermission_result::~AccumuloProxy_revokeTablePermission_result() noexcept {
}


uint32_t AccumuloProxy_revokeTablePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_revokeTablePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_revokeTablePermission_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeTablePermission_presult::~AccumuloProxy_revokeTablePermission_presult() noexcept {
}


uint32_t AccumuloProxy_revokeTablePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_grantNamespacePermission_args::~AccumuloProxy_grantNamespacePermission_args() noexcept {
}


uint32_t AccumuloProxy_grantNamespacePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast550;
          xfer += iprot->readI32(ecast550);
          this->perm = static_cast<NamespacePermission::type>(ecast550);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_grantNamespacePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_grantNamespacePermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantNamespacePermission_pargs::~AccumuloProxy_grantNamespacePermission_pargs() noexcept {
}


uint32_t AccumuloProxy_grantNamespacePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_grantNamespacePermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantNamespacePermission_result::~AccumuloProxy_grantNamespacePermission_result() noexcept {
}


uint32_t AccumuloProxy_grantNamespacePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_grantNamespacePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_grantNamespacePermission_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_grantNamespacePermission_presult::~AccumuloProxy_grantNamespacePermission_presult() noexcept {
}


uint32_t AccumuloProxy_grantNamespacePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_hasNamespacePermission_args::~AccumuloProxy_hasNamespacePermission_args() noexcept {
}


uint32_t AccumuloProxy_hasNamespacePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast551;
          xfer += iprot->readI32(ecast551);
          this->perm = static_cast<NamespacePermission::type>(ecast551);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasNamespacePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasNamespacePermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasNamespacePermission_pargs::~AccumuloProxy_hasNamespacePermission_pargs() noexcept {
}


uint32_t AccumuloProxy_hasNamespacePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasNamespacePermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasNamespacePermission_result::~AccumuloProxy_hasNamespacePermission_result() noexcept {
}


uint32_t AccumuloProxy_hasNamespacePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasNamespacePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_hasNamespacePermission_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasNamespacePermission_presult::~AccumuloProxy_hasNamespacePermission_presult() noexcept {
}


uint32_t AccumuloProxy_hasNamespacePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_revokeNamespacePermission_args::~AccumuloProxy_revokeNamespacePermission_args() noexcept {
}


uint32_t AccumuloProxy_revokeNamespacePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->user);
          this->__isset.user = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast552;
          xfer += iprot->readI32(ecast552);
          this->perm = static_cast<NamespacePermission::type>(ecast552);
          this->__isset.perm = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_revokeNamespacePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_revokeNamespacePermission_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->user);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->perm));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeNamespacePermission_pargs::~AccumuloProxy_revokeNamespacePermission_pargs() noexcept {
}


uint32_t AccumuloProxy_revokeNamespacePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_revokeNamespacePermission_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->user)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->perm))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeNamespacePermission_result::~AccumuloProxy_revokeNamespacePermission_result() noexcept {
}


uint32_t AccumuloProxy_revokeNamespacePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_revokeNamespacePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_revokeNamespacePermission_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_revokeNamespacePermission_presult::~AccumuloProxy_revokeNamespacePermission_presult() noexcept {
}


uint32_t AccumuloProxy_revokeNamespacePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createBatchScanner_args::~AccumuloProxy_createBatchScanner_args() noexcept {
}


uint32_t AccumuloProxy_createBatchScanner_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->options.read(iprot);
          this->__isset.options = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createBatchScanner_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createBatchScanner_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->options.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createBatchScanner_pargs::~AccumuloProxy_createBatchScanner_pargs() noexcept {
}


uint32_t AccumuloProxy_createBatchScanner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createBatchScanner_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->options)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createBatchScanner_result::~AccumuloProxy_createBatchScanner_result() noexcept {
}


uint32_t AccumuloProxy_createBatchScanner_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createBatchScanner_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createBatchScanner_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeString(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createBatchScanner_presult::~AccumuloProxy_createBatchScanner_presult() noexcept {
}


uint32_t AccumuloProxy_createBatchScanner_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createScanner_args::~AccumuloProxy_createScanner_args() noexcept {
}


uint32_t AccumuloProxy_createScanner_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->options.read(iprot);
          this->__isset.options = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createScanner_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createScanner_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->options.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createScanner_pargs::~AccumuloProxy_createScanner_pargs() noexcept {
}


uint32_t AccumuloProxy_createScanner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createScanner_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->options)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createScanner_result::~AccumuloProxy_createScanner_result() noexcept {
}


uint32_t AccumuloProxy_createScanner_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createScanner_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createScanner_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeString(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createScanner_presult::~AccumuloProxy_createScanner_presult() noexcept {
}


uint32_t AccumuloProxy_createScanner_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_hasNext_args::~AccumuloProxy_hasNext_args() noexcept {
}


uint32_t AccumuloProxy_hasNext_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->scanner);
          this->__isset.scanner = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasNext_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasNext_args");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->scanner);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasNext_pargs::~AccumuloProxy_hasNext_pargs() noexcept {
}


uint32_t AccumuloProxy_hasNext_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_hasNext_pargs");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->scanner)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasNext_result::~AccumuloProxy_hasNext_result() noexcept {
}


uint32_t AccumuloProxy_hasNext_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_hasNext_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_hasNext_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_hasNext_presult::~AccumuloProxy_hasNext_presult() noexcept {
}


uint32_t AccumuloProxy_hasNext_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_nextEntry_args::~AccumuloProxy_nextEntry_args() noexcept {
}


uint32_t AccumuloProxy_nextEntry_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->scanner);
          this->__isset.scanner = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_nextEntry_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_nextEntry_args");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->scanner);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_nextEntry_pargs::~AccumuloProxy_nextEntry_pargs() noexcept {
}


uint32_t AccumuloProxy_nextEntry_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_nextEntry_pargs");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->scanner)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_nextEntry_result::~AccumuloProxy_nextEntry_result() noexcept {
}


uint32_t AccumuloProxy_nextEntry_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->success.read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_nextEntry_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_nextEntry_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
    xfer += this->success.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_nextEntry_presult::~AccumuloProxy_nextEntry_presult() noexcept {
}


uint32_t AccumuloProxy_nextEntry_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += (*(this->success)).read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_nextK_args::~AccumuloProxy_nextK_args() noexcept {
}


uint32_t AccumuloProxy_nextK_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->scanner);
          this->__isset.scanner = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->k);
          this->__isset.k = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_nextK_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_nextK_args");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->scanner);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("k", ::apache::thrift::protocol::T_I32, 2);
  xfer += oprot->writeI32(this->k);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_nextK_pargs::~AccumuloProxy_nextK_pargs() noexcept {
}


uint32_t AccumuloProxy_nextK_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_nextK_pargs");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->scanner)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("k", ::apache::thrift::protocol::T_I32, 2);
  xfer += oprot->writeI32((*(this->k)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_nextK_result::~AccumuloProxy_nextK_result() noexcept {
}


uint32_t AccumuloProxy_nextK_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->success.read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_nextK_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_nextK_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
    xfer += this->success.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_nextK_presult::~AccumuloProxy_nextK_presult() noexcept {
}


uint32_t AccumuloProxy_nextK_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += (*(this->success)).read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_closeScanner_args::~AccumuloProxy_closeScanner_args() noexcept {
}


uint32_t AccumuloProxy_closeScanner_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->scanner);
          this->__isset.scanner = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_closeScanner_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_closeScanner_args");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->scanner);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeScanner_pargs::~AccumuloProxy_closeScanner_pargs() noexcept {
}


uint32_t AccumuloProxy_closeScanner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_closeScanner_pargs");

  xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->scanner)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeScanner_result::~AccumuloProxy_closeScanner_result() noexcept {
}


uint32_t AccumuloProxy_closeScanner_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_closeScanner_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_closeScanner_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeScanner_presult::~AccumuloProxy_closeScanner_presult() noexcept {
}


uint32_t AccumuloProxy_closeScanner_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_updateAndFlush_args::~AccumuloProxy_updateAndFlush_args() noexcept {
}


uint32_t AccumuloProxy_updateAndFlush_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->cells.clear();
            uint32_t _size553;
            ::apache::thrift::protocol::TType _ktype554;
            ::apache::thrift::protocol::TType _vtype555;
            xfer += iprot->readMapBegin(_ktype554, _vtype555, _size553);
            uint32_t _i557;
            for (_i557 = 0; _i557 < _size553; ++_i557)
            {
              std::string _key558;
              xfer += iprot->readBinary(_key558);
              std::vector<ColumnUpdate> & _val559 = this->cells[_key558];
              {
                _val559.clear();
                uint32_t _size560;
                ::apache::thrift::protocol::TType _etype563;
                xfer += iprot->readListBegin(_etype563, _size560);
                _val559.resize(_size560);
                uint32_t _i564;
                for (_i564 = 0; _i564 < _size560; ++_i564)
                {
                  xfer += _val559[_i564].read(iprot);
                }
                xfer += iprot->readListEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.cells = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_updateAndFlush_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_updateAndFlush_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 3);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>(this->cells.size()));
    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter565;
    for (_iter565 = this->cells.begin(); _iter565 != this->cells.end(); ++_iter565)
    {
      xfer += oprot->writeBinary(_iter565->first);
      {
        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter565->second.size()));
        std::vector<ColumnUpdate> ::const_iterator _iter566;
        for (_iter566 = _iter565->second.begin(); _iter566 != _iter565->second.end(); ++_iter566)
        {
          xfer += (*_iter566).write(oprot);
        }
        xfer += oprot->writeListEnd();
      }
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateAndFlush_pargs::~AccumuloProxy_updateAndFlush_pargs() noexcept {
}


uint32_t AccumuloProxy_updateAndFlush_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_updateAndFlush_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 3);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>((*(this->cells)).size()));
    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter567;
    for (_iter567 = (*(this->cells)).begin(); _iter567 != (*(this->cells)).end(); ++_iter567)
    {
      xfer += oprot->writeBinary(_iter567->first);
      {
        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter567->second.size()));
        std::vector<ColumnUpdate> ::const_iterator _iter568;
        for (_iter568 = _iter567->second.begin(); _iter568 != _iter567->second.end(); ++_iter568)
        {
          xfer += (*_iter568).write(oprot);
        }
        xfer += oprot->writeListEnd();
      }
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateAndFlush_result::~AccumuloProxy_updateAndFlush_result() noexcept {
}


uint32_t AccumuloProxy_updateAndFlush_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->outch1.read(iprot);
          this->__isset.outch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_updateAndFlush_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_updateAndFlush_result");

  if (this->__isset.outch1) {
    xfer += oprot->writeFieldBegin("outch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->outch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch4) {
    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
    xfer += this->ouch4.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateAndFlush_presult::~AccumuloProxy_updateAndFlush_presult() noexcept {
}


uint32_t AccumuloProxy_updateAndFlush_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->outch1.read(iprot);
          this->__isset.outch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createWriter_args::~AccumuloProxy_createWriter_args() noexcept {
}


uint32_t AccumuloProxy_createWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->opts.read(iprot);
          this->__isset.opts = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createWriter_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("opts", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->opts.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createWriter_pargs::~AccumuloProxy_createWriter_pargs() noexcept {
}


uint32_t AccumuloProxy_createWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createWriter_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("opts", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->opts)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createWriter_result::~AccumuloProxy_createWriter_result() noexcept {
}


uint32_t AccumuloProxy_createWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->outch1.read(iprot);
          this->__isset.outch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createWriter_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createWriter_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeString(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.outch1) {
    xfer += oprot->writeFieldBegin("outch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->outch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createWriter_presult::~AccumuloProxy_createWriter_presult() noexcept {
}


uint32_t AccumuloProxy_createWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->outch1.read(iprot);
          this->__isset.outch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_update_args::~AccumuloProxy_update_args() noexcept {
}


uint32_t AccumuloProxy_update_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->writer);
          this->__isset.writer = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->cells.clear();
            uint32_t _size569;
            ::apache::thrift::protocol::TType _ktype570;
            ::apache::thrift::protocol::TType _vtype571;
            xfer += iprot->readMapBegin(_ktype570, _vtype571, _size569);
            uint32_t _i573;
            for (_i573 = 0; _i573 < _size569; ++_i573)
            {
              std::string _key574;
              xfer += iprot->readBinary(_key574);
              std::vector<ColumnUpdate> & _val575 = this->cells[_key574];
              {
                _val575.clear();
                uint32_t _size576;
                ::apache::thrift::protocol::TType _etype579;
                xfer += iprot->readListBegin(_etype579, _size576);
                _val575.resize(_size576);
                uint32_t _i580;
                for (_i580 = 0; _i580 < _size576; ++_i580)
                {
                  xfer += _val575[_i580].read(iprot);
                }
                xfer += iprot->readListEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.cells = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_update_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_update_args");

  xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->writer);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 2);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>(this->cells.size()));
    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter581;
    for (_iter581 = this->cells.begin(); _iter581 != this->cells.end(); ++_iter581)
    {
      xfer += oprot->writeBinary(_iter581->first);
      {
        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter581->second.size()));
        std::vector<ColumnUpdate> ::const_iterator _iter582;
        for (_iter582 = _iter581->second.begin(); _iter582 != _iter581->second.end(); ++_iter582)
        {
          xfer += (*_iter582).write(oprot);
        }
        xfer += oprot->writeListEnd();
      }
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_update_pargs::~AccumuloProxy_update_pargs() noexcept {
}


uint32_t AccumuloProxy_update_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_update_pargs");

  xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->writer)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 2);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>((*(this->cells)).size()));
    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter583;
    for (_iter583 = (*(this->cells)).begin(); _iter583 != (*(this->cells)).end(); ++_iter583)
    {
      xfer += oprot->writeBinary(_iter583->first);
      {
        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter583->second.size()));
        std::vector<ColumnUpdate> ::const_iterator _iter584;
        for (_iter584 = _iter583->second.begin(); _iter584 != _iter583->second.end(); ++_iter584)
        {
          xfer += (*_iter584).write(oprot);
        }
        xfer += oprot->writeListEnd();
      }
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flush_args::~AccumuloProxy_flush_args() noexcept {
}


uint32_t AccumuloProxy_flush_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->writer);
          this->__isset.writer = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_flush_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_flush_args");

  xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->writer);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flush_pargs::~AccumuloProxy_flush_pargs() noexcept {
}


uint32_t AccumuloProxy_flush_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_flush_pargs");

  xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->writer)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flush_result::~AccumuloProxy_flush_result() noexcept {
}


uint32_t AccumuloProxy_flush_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_flush_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_flush_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_flush_presult::~AccumuloProxy_flush_presult() noexcept {
}


uint32_t AccumuloProxy_flush_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_closeWriter_args::~AccumuloProxy_closeWriter_args() noexcept {
}


uint32_t AccumuloProxy_closeWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->writer);
          this->__isset.writer = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_closeWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_closeWriter_args");

  xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->writer);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeWriter_pargs::~AccumuloProxy_closeWriter_pargs() noexcept {
}


uint32_t AccumuloProxy_closeWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_closeWriter_pargs");

  xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->writer)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeWriter_result::~AccumuloProxy_closeWriter_result() noexcept {
}


uint32_t AccumuloProxy_closeWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_closeWriter_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_closeWriter_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeWriter_presult::~AccumuloProxy_closeWriter_presult() noexcept {
}


uint32_t AccumuloProxy_closeWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_updateRowConditionally_args::~AccumuloProxy_updateRowConditionally_args() noexcept {
}


uint32_t AccumuloProxy_updateRowConditionally_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->row);
          this->__isset.row = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->updates.read(iprot);
          this->__isset.updates = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_updateRowConditionally_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_updateRowConditionally_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary(this->row);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_STRUCT, 4);
  xfer += this->updates.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateRowConditionally_pargs::~AccumuloProxy_updateRowConditionally_pargs() noexcept {
}


uint32_t AccumuloProxy_updateRowConditionally_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_updateRowConditionally_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeBinary((*(this->row)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_STRUCT, 4);
  xfer += (*(this->updates)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateRowConditionally_result::~AccumuloProxy_updateRowConditionally_result() noexcept {
}


uint32_t AccumuloProxy_updateRowConditionally_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast585;
          xfer += iprot->readI32(ecast585);
          this->success = static_cast<ConditionalStatus::type>(ecast585);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_updateRowConditionally_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_updateRowConditionally_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_I32, 0);
    xfer += oprot->writeI32(static_cast<int32_t>(this->success));
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateRowConditionally_presult::~AccumuloProxy_updateRowConditionally_presult() noexcept {
}


uint32_t AccumuloProxy_updateRowConditionally_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast586;
          xfer += iprot->readI32(ecast586);
          (*(this->success)) = static_cast<ConditionalStatus::type>(ecast586);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createConditionalWriter_args::~AccumuloProxy_createConditionalWriter_args() noexcept {
}


uint32_t AccumuloProxy_createConditionalWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->tableName);
          this->__isset.tableName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->options.read(iprot);
          this->__isset.options = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createConditionalWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createConditionalWriter_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->tableName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->options.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createConditionalWriter_pargs::~AccumuloProxy_createConditionalWriter_pargs() noexcept {
}


uint32_t AccumuloProxy_createConditionalWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createConditionalWriter_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("tableName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->tableName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->options)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createConditionalWriter_result::~AccumuloProxy_createConditionalWriter_result() noexcept {
}


uint32_t AccumuloProxy_createConditionalWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createConditionalWriter_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createConditionalWriter_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeString(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createConditionalWriter_presult::~AccumuloProxy_createConditionalWriter_presult() noexcept {
}


uint32_t AccumuloProxy_createConditionalWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_updateRowsConditionally_args::~AccumuloProxy_updateRowsConditionally_args() noexcept {
}


uint32_t AccumuloProxy_updateRowsConditionally_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->conditionalWriter);
          this->__isset.conditionalWriter = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->updates.clear();
            uint32_t _size587;
            ::apache::thrift::protocol::TType _ktype588;
            ::apache::thrift::protocol::TType _vtype589;
            xfer += iprot->readMapBegin(_ktype588, _vtype589, _size587);
            uint32_t _i591;
            for (_i591 = 0; _i591 < _size587; ++_i591)
            {
              std::string _key592;
              xfer += iprot->readBinary(_key592);
              ConditionalUpdates& _val593 = this->updates[_key592];
              xfer += _val593.read(iprot);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.updates = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_updateRowsConditionally_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_updateRowsConditionally_args");

  xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->conditionalWriter);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_MAP, 2);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->updates.size()));
    std::map<std::string, ConditionalUpdates> ::const_iterator _iter594;
    for (_iter594 = this->updates.begin(); _iter594 != this->updates.end(); ++_iter594)
    {
      xfer += oprot->writeBinary(_iter594->first);
      xfer += _iter594->second.write(oprot);
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateRowsConditionally_pargs::~AccumuloProxy_updateRowsConditionally_pargs() noexcept {
}


uint32_t AccumuloProxy_updateRowsConditionally_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_updateRowsConditionally_pargs");

  xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->conditionalWriter)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_MAP, 2);
  {
    xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->updates)).size()));
    std::map<std::string, ConditionalUpdates> ::const_iterator _iter595;
    for (_iter595 = (*(this->updates)).begin(); _iter595 != (*(this->updates)).end(); ++_iter595)
    {
      xfer += oprot->writeBinary(_iter595->first);
      xfer += _iter595->second.write(oprot);
    }
    xfer += oprot->writeMapEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateRowsConditionally_result::~AccumuloProxy_updateRowsConditionally_result() noexcept {
}


uint32_t AccumuloProxy_updateRowsConditionally_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size596;
            ::apache::thrift::protocol::TType _ktype597;
            ::apache::thrift::protocol::TType _vtype598;
            xfer += iprot->readMapBegin(_ktype597, _vtype598, _size596);
            uint32_t _i600;
            for (_i600 = 0; _i600 < _size596; ++_i600)
            {
              std::string _key601;
              xfer += iprot->readBinary(_key601);
              ConditionalStatus::type& _val602 = this->success[_key601];
              int32_t ecast603;
              xfer += iprot->readI32(ecast603);
              _val602 = static_cast<ConditionalStatus::type>(ecast603);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_updateRowsConditionally_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_updateRowsConditionally_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, ConditionalStatus::type> ::const_iterator _iter604;
      for (_iter604 = this->success.begin(); _iter604 != this->success.end(); ++_iter604)
      {
        xfer += oprot->writeBinary(_iter604->first);
        xfer += oprot->writeI32(static_cast<int32_t>(_iter604->second));
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_updateRowsConditionally_presult::~AccumuloProxy_updateRowsConditionally_presult() noexcept {
}


uint32_t AccumuloProxy_updateRowsConditionally_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size605;
            ::apache::thrift::protocol::TType _ktype606;
            ::apache::thrift::protocol::TType _vtype607;
            xfer += iprot->readMapBegin(_ktype606, _vtype607, _size605);
            uint32_t _i609;
            for (_i609 = 0; _i609 < _size605; ++_i609)
            {
              std::string _key610;
              xfer += iprot->readBinary(_key610);
              ConditionalStatus::type& _val611 = (*(this->success))[_key610];
              int32_t ecast612;
              xfer += iprot->readI32(ecast612);
              _val611 = static_cast<ConditionalStatus::type>(ecast612);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_closeConditionalWriter_args::~AccumuloProxy_closeConditionalWriter_args() noexcept {
}


uint32_t AccumuloProxy_closeConditionalWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->conditionalWriter);
          this->__isset.conditionalWriter = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_closeConditionalWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_closeConditionalWriter_args");

  xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->conditionalWriter);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeConditionalWriter_pargs::~AccumuloProxy_closeConditionalWriter_pargs() noexcept {
}


uint32_t AccumuloProxy_closeConditionalWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_closeConditionalWriter_pargs");

  xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->conditionalWriter)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeConditionalWriter_result::~AccumuloProxy_closeConditionalWriter_result() noexcept {
}


uint32_t AccumuloProxy_closeConditionalWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    xfer += iprot->skip(ftype);
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_closeConditionalWriter_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_closeConditionalWriter_result");

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_closeConditionalWriter_presult::~AccumuloProxy_closeConditionalWriter_presult() noexcept {
}


uint32_t AccumuloProxy_closeConditionalWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    xfer += iprot->skip(ftype);
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getRowRange_args::~AccumuloProxy_getRowRange_args() noexcept {
}


uint32_t AccumuloProxy_getRowRange_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readBinary(this->row);
          this->__isset.row = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getRowRange_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getRowRange_args");

  xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeBinary(this->row);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getRowRange_pargs::~AccumuloProxy_getRowRange_pargs() noexcept {
}


uint32_t AccumuloProxy_getRowRange_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getRowRange_pargs");

  xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeBinary((*(this->row)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getRowRange_result::~AccumuloProxy_getRowRange_result() noexcept {
}


uint32_t AccumuloProxy_getRowRange_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->success.read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getRowRange_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getRowRange_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
    xfer += this->success.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getRowRange_presult::~AccumuloProxy_getRowRange_presult() noexcept {
}


uint32_t AccumuloProxy_getRowRange_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += (*(this->success)).read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getFollowing_args::~AccumuloProxy_getFollowing_args() noexcept {
}


uint32_t AccumuloProxy_getFollowing_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->key.read(iprot);
          this->__isset.key = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast613;
          xfer += iprot->readI32(ecast613);
          this->part = static_cast<PartialKey::type>(ecast613);
          this->__isset.part = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getFollowing_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getFollowing_args");

  xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRUCT, 1);
  xfer += this->key.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("part", ::apache::thrift::protocol::T_I32, 2);
  xfer += oprot->writeI32(static_cast<int32_t>(this->part));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getFollowing_pargs::~AccumuloProxy_getFollowing_pargs() noexcept {
}


uint32_t AccumuloProxy_getFollowing_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getFollowing_pargs");

  xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRUCT, 1);
  xfer += (*(this->key)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("part", ::apache::thrift::protocol::T_I32, 2);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->part))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getFollowing_result::~AccumuloProxy_getFollowing_result() noexcept {
}


uint32_t AccumuloProxy_getFollowing_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->success.read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getFollowing_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getFollowing_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
    xfer += this->success.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getFollowing_presult::~AccumuloProxy_getFollowing_presult() noexcept {
}


uint32_t AccumuloProxy_getFollowing_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += (*(this->success)).read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_systemNamespace_args::~AccumuloProxy_systemNamespace_args() noexcept {
}


uint32_t AccumuloProxy_systemNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    xfer += iprot->skip(ftype);
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_systemNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_systemNamespace_args");

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_systemNamespace_pargs::~AccumuloProxy_systemNamespace_pargs() noexcept {
}


uint32_t AccumuloProxy_systemNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_systemNamespace_pargs");

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_systemNamespace_result::~AccumuloProxy_systemNamespace_result() noexcept {
}


uint32_t AccumuloProxy_systemNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_systemNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_systemNamespace_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeString(this->success);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_systemNamespace_presult::~AccumuloProxy_systemNamespace_presult() noexcept {
}


uint32_t AccumuloProxy_systemNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_defaultNamespace_args::~AccumuloProxy_defaultNamespace_args() noexcept {
}


uint32_t AccumuloProxy_defaultNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    xfer += iprot->skip(ftype);
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_defaultNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_defaultNamespace_args");

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_defaultNamespace_pargs::~AccumuloProxy_defaultNamespace_pargs() noexcept {
}


uint32_t AccumuloProxy_defaultNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_defaultNamespace_pargs");

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_defaultNamespace_result::~AccumuloProxy_defaultNamespace_result() noexcept {
}


uint32_t AccumuloProxy_defaultNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_defaultNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_defaultNamespace_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
    xfer += oprot->writeString(this->success);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_defaultNamespace_presult::~AccumuloProxy_defaultNamespace_presult() noexcept {
}


uint32_t AccumuloProxy_defaultNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listNamespaces_args::~AccumuloProxy_listNamespaces_args() noexcept {
}


uint32_t AccumuloProxy_listNamespaces_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listNamespaces_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaces_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaces_pargs::~AccumuloProxy_listNamespaces_pargs() noexcept {
}


uint32_t AccumuloProxy_listNamespaces_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaces_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaces_result::~AccumuloProxy_listNamespaces_result() noexcept {
}


uint32_t AccumuloProxy_listNamespaces_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->success.clear();
            uint32_t _size614;
            ::apache::thrift::protocol::TType _etype617;
            xfer += iprot->readListBegin(_etype617, _size614);
            this->success.resize(_size614);
            uint32_t _i618;
            for (_i618 = 0; _i618 < _size614; ++_i618)
            {
              xfer += iprot->readString(this->success[_i618]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listNamespaces_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaces_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::vector<std::string> ::const_iterator _iter619;
      for (_iter619 = this->success.begin(); _iter619 != this->success.end(); ++_iter619)
      {
        xfer += oprot->writeString((*_iter619));
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaces_presult::~AccumuloProxy_listNamespaces_presult() noexcept {
}


uint32_t AccumuloProxy_listNamespaces_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            (*(this->success)).clear();
            uint32_t _size620;
            ::apache::thrift::protocol::TType _etype623;
            xfer += iprot->readListBegin(_etype623, _size620);
            (*(this->success)).resize(_size620);
            uint32_t _i624;
            for (_i624 = 0; _i624 < _size620; ++_i624)
            {
              xfer += iprot->readString((*(this->success))[_i624]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_namespaceExists_args::~AccumuloProxy_namespaceExists_args() noexcept {
}


uint32_t AccumuloProxy_namespaceExists_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_namespaceExists_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceExists_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_namespaceExists_pargs::~AccumuloProxy_namespaceExists_pargs() noexcept {
}


uint32_t AccumuloProxy_namespaceExists_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceExists_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_namespaceExists_result::~AccumuloProxy_namespaceExists_result() noexcept {
}


uint32_t AccumuloProxy_namespaceExists_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_namespaceExists_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceExists_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_namespaceExists_presult::~AccumuloProxy_namespaceExists_presult() noexcept {
}


uint32_t AccumuloProxy_namespaceExists_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_createNamespace_args::~AccumuloProxy_createNamespace_args() noexcept {
}


uint32_t AccumuloProxy_createNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createNamespace_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createNamespace_pargs::~AccumuloProxy_createNamespace_pargs() noexcept {
}


uint32_t AccumuloProxy_createNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_createNamespace_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createNamespace_result::~AccumuloProxy_createNamespace_result() noexcept {
}


uint32_t AccumuloProxy_createNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_createNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_createNamespace_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_createNamespace_presult::~AccumuloProxy_createNamespace_presult() noexcept {
}


uint32_t AccumuloProxy_createNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_deleteNamespace_args::~AccumuloProxy_deleteNamespace_args() noexcept {
}


uint32_t AccumuloProxy_deleteNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_deleteNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_deleteNamespace_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteNamespace_pargs::~AccumuloProxy_deleteNamespace_pargs() noexcept {
}


uint32_t AccumuloProxy_deleteNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_deleteNamespace_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteNamespace_result::~AccumuloProxy_deleteNamespace_result() noexcept {
}


uint32_t AccumuloProxy_deleteNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_deleteNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_deleteNamespace_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch4) {
    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
    xfer += this->ouch4.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_deleteNamespace_presult::~AccumuloProxy_deleteNamespace_presult() noexcept {
}


uint32_t AccumuloProxy_deleteNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_renameNamespace_args::~AccumuloProxy_renameNamespace_args() noexcept {
}


uint32_t AccumuloProxy_renameNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->oldNamespaceName);
          this->__isset.oldNamespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->newNamespaceName);
          this->__isset.newNamespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_renameNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_renameNamespace_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("oldNamespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->oldNamespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("newNamespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->newNamespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_renameNamespace_pargs::~AccumuloProxy_renameNamespace_pargs() noexcept {
}


uint32_t AccumuloProxy_renameNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_renameNamespace_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("oldNamespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->oldNamespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("newNamespaceName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->newNamespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_renameNamespace_result::~AccumuloProxy_renameNamespace_result() noexcept {
}


uint32_t AccumuloProxy_renameNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_renameNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_renameNamespace_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch4) {
    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
    xfer += this->ouch4.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_renameNamespace_presult::~AccumuloProxy_renameNamespace_presult() noexcept {
}


uint32_t AccumuloProxy_renameNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch4.read(iprot);
          this->__isset.ouch4 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_setNamespaceProperty_args::~AccumuloProxy_setNamespaceProperty_args() noexcept {
}


uint32_t AccumuloProxy_setNamespaceProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->property);
          this->__isset.property = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->value);
          this->__isset.value = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setNamespaceProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setNamespaceProperty_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->property);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString(this->value);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setNamespaceProperty_pargs::~AccumuloProxy_setNamespaceProperty_pargs() noexcept {
}


uint32_t AccumuloProxy_setNamespaceProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_setNamespaceProperty_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->property)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString((*(this->value)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setNamespaceProperty_result::~AccumuloProxy_setNamespaceProperty_result() noexcept {
}


uint32_t AccumuloProxy_setNamespaceProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_setNamespaceProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_setNamespaceProperty_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_setNamespaceProperty_presult::~AccumuloProxy_setNamespaceProperty_presult() noexcept {
}


uint32_t AccumuloProxy_setNamespaceProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeNamespaceProperty_args::~AccumuloProxy_removeNamespaceProperty_args() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->property);
          this->__isset.property = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeNamespaceProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceProperty_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->property);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceProperty_pargs::~AccumuloProxy_removeNamespaceProperty_pargs() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceProperty_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->property)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceProperty_result::~AccumuloProxy_removeNamespaceProperty_result() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeNamespaceProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceProperty_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceProperty_presult::~AccumuloProxy_removeNamespaceProperty_presult() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getNamespaceProperties_args::~AccumuloProxy_getNamespaceProperties_args() noexcept {
}


uint32_t AccumuloProxy_getNamespaceProperties_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getNamespaceProperties_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceProperties_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getNamespaceProperties_pargs::~AccumuloProxy_getNamespaceProperties_pargs() noexcept {
}


uint32_t AccumuloProxy_getNamespaceProperties_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceProperties_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getNamespaceProperties_result::~AccumuloProxy_getNamespaceProperties_result() noexcept {
}


uint32_t AccumuloProxy_getNamespaceProperties_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size625;
            ::apache::thrift::protocol::TType _ktype626;
            ::apache::thrift::protocol::TType _vtype627;
            xfer += iprot->readMapBegin(_ktype626, _vtype627, _size625);
            uint32_t _i629;
            for (_i629 = 0; _i629 < _size625; ++_i629)
            {
              std::string _key630;
              xfer += iprot->readString(_key630);
              std::string& _val631 = this->success[_key630];
              xfer += iprot->readString(_val631);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getNamespaceProperties_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceProperties_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::string> ::const_iterator _iter632;
      for (_iter632 = this->success.begin(); _iter632 != this->success.end(); ++_iter632)
      {
        xfer += oprot->writeString(_iter632->first);
        xfer += oprot->writeString(_iter632->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getNamespaceProperties_presult::~AccumuloProxy_getNamespaceProperties_presult() noexcept {
}


uint32_t AccumuloProxy_getNamespaceProperties_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size633;
            ::apache::thrift::protocol::TType _ktype634;
            ::apache::thrift::protocol::TType _vtype635;
            xfer += iprot->readMapBegin(_ktype634, _vtype635, _size633);
            uint32_t _i637;
            for (_i637 = 0; _i637 < _size633; ++_i637)
            {
              std::string _key638;
              xfer += iprot->readString(_key638);
              std::string& _val639 = (*(this->success))[_key638];
              xfer += iprot->readString(_val639);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_namespaceIdMap_args::~AccumuloProxy_namespaceIdMap_args() noexcept {
}


uint32_t AccumuloProxy_namespaceIdMap_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_namespaceIdMap_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceIdMap_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_namespaceIdMap_pargs::~AccumuloProxy_namespaceIdMap_pargs() noexcept {
}


uint32_t AccumuloProxy_namespaceIdMap_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceIdMap_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_namespaceIdMap_result::~AccumuloProxy_namespaceIdMap_result() noexcept {
}


uint32_t AccumuloProxy_namespaceIdMap_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size640;
            ::apache::thrift::protocol::TType _ktype641;
            ::apache::thrift::protocol::TType _vtype642;
            xfer += iprot->readMapBegin(_ktype641, _vtype642, _size640);
            uint32_t _i644;
            for (_i644 = 0; _i644 < _size640; ++_i644)
            {
              std::string _key645;
              xfer += iprot->readString(_key645);
              std::string& _val646 = this->success[_key645];
              xfer += iprot->readString(_val646);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_namespaceIdMap_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceIdMap_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::string> ::const_iterator _iter647;
      for (_iter647 = this->success.begin(); _iter647 != this->success.end(); ++_iter647)
      {
        xfer += oprot->writeString(_iter647->first);
        xfer += oprot->writeString(_iter647->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_namespaceIdMap_presult::~AccumuloProxy_namespaceIdMap_presult() noexcept {
}


uint32_t AccumuloProxy_namespaceIdMap_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size648;
            ::apache::thrift::protocol::TType _ktype649;
            ::apache::thrift::protocol::TType _vtype650;
            xfer += iprot->readMapBegin(_ktype649, _vtype650, _size648);
            uint32_t _i652;
            for (_i652 = 0; _i652 < _size648; ++_i652)
            {
              std::string _key653;
              xfer += iprot->readString(_key653);
              std::string& _val654 = (*(this->success))[_key653];
              xfer += iprot->readString(_val654);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_attachNamespaceIterator_args::~AccumuloProxy_attachNamespaceIterator_args() noexcept {
}


uint32_t AccumuloProxy_attachNamespaceIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->setting.read(iprot);
          this->__isset.setting = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->scopes.clear();
            uint32_t _size655;
            ::apache::thrift::protocol::TType _etype658;
            xfer += iprot->readSetBegin(_etype658, _size655);
            uint32_t _i659;
            for (_i659 = 0; _i659 < _size655; ++_i659)
            {
              IteratorScope::type _elem660;
              int32_t ecast661;
              xfer += iprot->readI32(ecast661);
              _elem660 = static_cast<IteratorScope::type>(ecast661);
              this->scopes.insert(_elem660);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.scopes = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_attachNamespaceIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_attachNamespaceIterator_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->setting.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
    std::set<IteratorScope::type> ::const_iterator _iter662;
    for (_iter662 = this->scopes.begin(); _iter662 != this->scopes.end(); ++_iter662)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter662)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_attachNamespaceIterator_pargs::~AccumuloProxy_attachNamespaceIterator_pargs() noexcept {
}


uint32_t AccumuloProxy_attachNamespaceIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_attachNamespaceIterator_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->setting)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
    std::set<IteratorScope::type> ::const_iterator _iter663;
    for (_iter663 = (*(this->scopes)).begin(); _iter663 != (*(this->scopes)).end(); ++_iter663)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter663)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_attachNamespaceIterator_result::~AccumuloProxy_attachNamespaceIterator_result() noexcept {
}


uint32_t AccumuloProxy_attachNamespaceIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_attachNamespaceIterator_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_attachNamespaceIterator_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_attachNamespaceIterator_presult::~AccumuloProxy_attachNamespaceIterator_presult() noexcept {
}


uint32_t AccumuloProxy_attachNamespaceIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeNamespaceIterator_args::~AccumuloProxy_removeNamespaceIterator_args() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->name);
          this->__isset.name = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->scopes.clear();
            uint32_t _size664;
            ::apache::thrift::protocol::TType _etype667;
            xfer += iprot->readSetBegin(_etype667, _size664);
            uint32_t _i668;
            for (_i668 = 0; _i668 < _size664; ++_i668)
            {
              IteratorScope::type _elem669;
              int32_t ecast670;
              xfer += iprot->readI32(ecast670);
              _elem669 = static_cast<IteratorScope::type>(ecast670);
              this->scopes.insert(_elem669);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.scopes = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeNamespaceIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceIterator_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->name);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
    std::set<IteratorScope::type> ::const_iterator _iter671;
    for (_iter671 = this->scopes.begin(); _iter671 != this->scopes.end(); ++_iter671)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter671)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceIterator_pargs::~AccumuloProxy_removeNamespaceIterator_pargs() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceIterator_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->name)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
    std::set<IteratorScope::type> ::const_iterator _iter672;
    for (_iter672 = (*(this->scopes)).begin(); _iter672 != (*(this->scopes)).end(); ++_iter672)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter672)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceIterator_result::~AccumuloProxy_removeNamespaceIterator_result() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeNamespaceIterator_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceIterator_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceIterator_presult::~AccumuloProxy_removeNamespaceIterator_presult() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_getNamespaceIteratorSetting_args::~AccumuloProxy_getNamespaceIteratorSetting_args() noexcept {
}


uint32_t AccumuloProxy_getNamespaceIteratorSetting_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->name);
          this->__isset.name = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast673;
          xfer += iprot->readI32(ecast673);
          this->scope = static_cast<IteratorScope::type>(ecast673);
          this->__isset.scope = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getNamespaceIteratorSetting_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceIteratorSetting_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->name);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scope", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>(this->scope));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getNamespaceIteratorSetting_pargs::~AccumuloProxy_getNamespaceIteratorSetting_pargs() noexcept {
}


uint32_t AccumuloProxy_getNamespaceIteratorSetting_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceIteratorSetting_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->name)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scope", ::apache::thrift::protocol::T_I32, 4);
  xfer += oprot->writeI32(static_cast<int32_t>((*(this->scope))));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getNamespaceIteratorSetting_result::~AccumuloProxy_getNamespaceIteratorSetting_result() noexcept {
}


uint32_t AccumuloProxy_getNamespaceIteratorSetting_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->success.read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_getNamespaceIteratorSetting_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceIteratorSetting_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
    xfer += this->success.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_getNamespaceIteratorSetting_presult::~AccumuloProxy_getNamespaceIteratorSetting_presult() noexcept {
}


uint32_t AccumuloProxy_getNamespaceIteratorSetting_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += (*(this->success)).read(iprot);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listNamespaceIterators_args::~AccumuloProxy_listNamespaceIterators_args() noexcept {
}


uint32_t AccumuloProxy_listNamespaceIterators_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listNamespaceIterators_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceIterators_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaceIterators_pargs::~AccumuloProxy_listNamespaceIterators_pargs() noexcept {
}


uint32_t AccumuloProxy_listNamespaceIterators_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceIterators_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaceIterators_result::~AccumuloProxy_listNamespaceIterators_result() noexcept {
}


uint32_t AccumuloProxy_listNamespaceIterators_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size674;
            ::apache::thrift::protocol::TType _ktype675;
            ::apache::thrift::protocol::TType _vtype676;
            xfer += iprot->readMapBegin(_ktype675, _vtype676, _size674);
            uint32_t _i678;
            for (_i678 = 0; _i678 < _size674; ++_i678)
            {
              std::string _key679;
              xfer += iprot->readString(_key679);
              std::set<IteratorScope::type> & _val680 = this->success[_key679];
              {
                _val680.clear();
                uint32_t _size681;
                ::apache::thrift::protocol::TType _etype684;
                xfer += iprot->readSetBegin(_etype684, _size681);
                uint32_t _i685;
                for (_i685 = 0; _i685 < _size681; ++_i685)
                {
                  IteratorScope::type _elem686;
                  int32_t ecast687;
                  xfer += iprot->readI32(ecast687);
                  _elem686 = static_cast<IteratorScope::type>(ecast687);
                  _val680.insert(_elem686);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listNamespaceIterators_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceIterators_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, std::set<IteratorScope::type> > ::const_iterator _iter688;
      for (_iter688 = this->success.begin(); _iter688 != this->success.end(); ++_iter688)
      {
        xfer += oprot->writeString(_iter688->first);
        {
          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(_iter688->second.size()));
          std::set<IteratorScope::type> ::const_iterator _iter689;
          for (_iter689 = _iter688->second.begin(); _iter689 != _iter688->second.end(); ++_iter689)
          {
            xfer += oprot->writeI32(static_cast<int32_t>((*_iter689)));
          }
          xfer += oprot->writeSetEnd();
        }
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaceIterators_presult::~AccumuloProxy_listNamespaceIterators_presult() noexcept {
}


uint32_t AccumuloProxy_listNamespaceIterators_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size690;
            ::apache::thrift::protocol::TType _ktype691;
            ::apache::thrift::protocol::TType _vtype692;
            xfer += iprot->readMapBegin(_ktype691, _vtype692, _size690);
            uint32_t _i694;
            for (_i694 = 0; _i694 < _size690; ++_i694)
            {
              std::string _key695;
              xfer += iprot->readString(_key695);
              std::set<IteratorScope::type> & _val696 = (*(this->success))[_key695];
              {
                _val696.clear();
                uint32_t _size697;
                ::apache::thrift::protocol::TType _etype700;
                xfer += iprot->readSetBegin(_etype700, _size697);
                uint32_t _i701;
                for (_i701 = 0; _i701 < _size697; ++_i701)
                {
                  IteratorScope::type _elem702;
                  int32_t ecast703;
                  xfer += iprot->readI32(ecast703);
                  _elem702 = static_cast<IteratorScope::type>(ecast703);
                  _val696.insert(_elem702);
                }
                xfer += iprot->readSetEnd();
              }
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_checkNamespaceIteratorConflicts_args::~AccumuloProxy_checkNamespaceIteratorConflicts_args() noexcept {
}


uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->setting.read(iprot);
          this->__isset.setting = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_SET) {
          {
            this->scopes.clear();
            uint32_t _size704;
            ::apache::thrift::protocol::TType _etype707;
            xfer += iprot->readSetBegin(_etype707, _size704);
            uint32_t _i708;
            for (_i708 = 0; _i708 < _size704; ++_i708)
            {
              IteratorScope::type _elem709;
              int32_t ecast710;
              xfer += iprot->readI32(ecast710);
              _elem709 = static_cast<IteratorScope::type>(ecast710);
              this->scopes.insert(_elem709);
            }
            xfer += iprot->readSetEnd();
          }
          this->__isset.scopes = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_checkNamespaceIteratorConflicts_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += this->setting.write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
    std::set<IteratorScope::type> ::const_iterator _iter711;
    for (_iter711 = this->scopes.begin(); _iter711 != this->scopes.end(); ++_iter711)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter711)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_checkNamespaceIteratorConflicts_pargs::~AccumuloProxy_checkNamespaceIteratorConflicts_pargs() noexcept {
}


uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_checkNamespaceIteratorConflicts_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
  xfer += (*(this->setting)).write(oprot);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
  {
    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
    std::set<IteratorScope::type> ::const_iterator _iter712;
    for (_iter712 = (*(this->scopes)).begin(); _iter712 != (*(this->scopes)).end(); ++_iter712)
    {
      xfer += oprot->writeI32(static_cast<int32_t>((*_iter712)));
    }
    xfer += oprot->writeSetEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_checkNamespaceIteratorConflicts_result::~AccumuloProxy_checkNamespaceIteratorConflicts_result() noexcept {
}


uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_checkNamespaceIteratorConflicts_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_checkNamespaceIteratorConflicts_presult::~AccumuloProxy_checkNamespaceIteratorConflicts_presult() noexcept {
}


uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_addNamespaceConstraint_args::~AccumuloProxy_addNamespaceConstraint_args() noexcept {
}


uint32_t AccumuloProxy_addNamespaceConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->constraintClassName);
          this->__isset.constraintClassName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_addNamespaceConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_addNamespaceConstraint_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("constraintClassName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->constraintClassName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addNamespaceConstraint_pargs::~AccumuloProxy_addNamespaceConstraint_pargs() noexcept {
}


uint32_t AccumuloProxy_addNamespaceConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_addNamespaceConstraint_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("constraintClassName", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->constraintClassName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addNamespaceConstraint_result::~AccumuloProxy_addNamespaceConstraint_result() noexcept {
}


uint32_t AccumuloProxy_addNamespaceConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_addNamespaceConstraint_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_addNamespaceConstraint_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_I32, 0);
    xfer += oprot->writeI32(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_addNamespaceConstraint_presult::~AccumuloProxy_addNamespaceConstraint_presult() noexcept {
}


uint32_t AccumuloProxy_addNamespaceConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_removeNamespaceConstraint_args::~AccumuloProxy_removeNamespaceConstraint_args() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->id);
          this->__isset.id = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeNamespaceConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceConstraint_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("id", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32(this->id);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceConstraint_pargs::~AccumuloProxy_removeNamespaceConstraint_pargs() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceConstraint_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("id", ::apache::thrift::protocol::T_I32, 3);
  xfer += oprot->writeI32((*(this->id)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceConstraint_result::~AccumuloProxy_removeNamespaceConstraint_result() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_removeNamespaceConstraint_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceConstraint_result");

  if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_removeNamespaceConstraint_presult::~AccumuloProxy_removeNamespaceConstraint_presult() noexcept {
}


uint32_t AccumuloProxy_removeNamespaceConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_listNamespaceConstraints_args::~AccumuloProxy_listNamespaceConstraints_args() noexcept {
}


uint32_t AccumuloProxy_listNamespaceConstraints_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listNamespaceConstraints_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceConstraints_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaceConstraints_pargs::~AccumuloProxy_listNamespaceConstraints_pargs() noexcept {
}


uint32_t AccumuloProxy_listNamespaceConstraints_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceConstraints_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaceConstraints_result::~AccumuloProxy_listNamespaceConstraints_result() noexcept {
}


uint32_t AccumuloProxy_listNamespaceConstraints_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->success.clear();
            uint32_t _size713;
            ::apache::thrift::protocol::TType _ktype714;
            ::apache::thrift::protocol::TType _vtype715;
            xfer += iprot->readMapBegin(_ktype714, _vtype715, _size713);
            uint32_t _i717;
            for (_i717 = 0; _i717 < _size713; ++_i717)
            {
              std::string _key718;
              xfer += iprot->readString(_key718);
              int32_t& _val719 = this->success[_key718];
              xfer += iprot->readI32(_val719);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_listNamespaceConstraints_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceConstraints_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->success.size()));
      std::map<std::string, int32_t> ::const_iterator _iter720;
      for (_iter720 = this->success.begin(); _iter720 != this->success.end(); ++_iter720)
      {
        xfer += oprot->writeString(_iter720->first);
        xfer += oprot->writeI32(_iter720->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_listNamespaceConstraints_presult::~AccumuloProxy_listNamespaceConstraints_presult() noexcept {
}


uint32_t AccumuloProxy_listNamespaceConstraints_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            (*(this->success)).clear();
            uint32_t _size721;
            ::apache::thrift::protocol::TType _ktype722;
            ::apache::thrift::protocol::TType _vtype723;
            xfer += iprot->readMapBegin(_ktype722, _vtype723, _size721);
            uint32_t _i725;
            for (_i725 = 0; _i725 < _size721; ++_i725)
            {
              std::string _key726;
              xfer += iprot->readString(_key726);
              int32_t& _val727 = (*(this->success))[_key726];
              xfer += iprot->readI32(_val727);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}


AccumuloProxy_testNamespaceClassLoad_args::~AccumuloProxy_testNamespaceClassLoad_args() noexcept {
}


uint32_t AccumuloProxy_testNamespaceClassLoad_args::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->sharedSecret);
          this->__isset.sharedSecret = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->namespaceName);
          this->__isset.namespaceName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->className);
          this->__isset.className = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->asTypeName);
          this->__isset.asTypeName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_testNamespaceClassLoad_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_testNamespaceClassLoad_args");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->sharedSecret);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString(this->namespaceName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString(this->className);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString(this->asTypeName);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testNamespaceClassLoad_pargs::~AccumuloProxy_testNamespaceClassLoad_pargs() noexcept {
}


uint32_t AccumuloProxy_testNamespaceClassLoad_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("AccumuloProxy_testNamespaceClassLoad_pargs");

  xfer += oprot->writeFieldBegin("sharedSecret", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString((*(this->sharedSecret)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
  xfer += oprot->writeString((*(this->namespaceName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 3);
  xfer += oprot->writeString((*(this->className)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 4);
  xfer += oprot->writeString((*(this->asTypeName)));
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testNamespaceClassLoad_result::~AccumuloProxy_testNamespaceClassLoad_result() noexcept {
}


uint32_t AccumuloProxy_testNamespaceClassLoad_result::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->success);
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t AccumuloProxy_testNamespaceClassLoad_result::write(::apache::thrift::protocol::TProtocol* oprot) const {

  uint32_t xfer = 0;

  xfer += oprot->writeStructBegin("AccumuloProxy_testNamespaceClassLoad_result");

  if (this->__isset.success) {
    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
    xfer += oprot->writeBool(this->success);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch1) {
    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
    xfer += this->ouch1.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch2) {
    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
    xfer += this->ouch2.write(oprot);
    xfer += oprot->writeFieldEnd();
  } else if (this->__isset.ouch3) {
    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
    xfer += this->ouch3.write(oprot);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}


AccumuloProxy_testNamespaceClassLoad_presult::~AccumuloProxy_testNamespaceClassLoad_presult() noexcept {
}


uint32_t AccumuloProxy_testNamespaceClassLoad_presult::read(::apache::thrift::protocol::TProtocol* iprot) {

  ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 0:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool((*(this->success)));
          this->__isset.success = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch1.read(iprot);
          this->__isset.ouch1 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch2.read(iprot);
          this->__isset.ouch2 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
          xfer += this->ouch3.read(iprot);
          this->__isset.ouch3 = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

int32_t AccumuloProxyClient::addConstraint(const std::string& sharedSecret, const std::string& tableName, const std::string& constraintClassName)
{
  send_addConstraint(sharedSecret, tableName, constraintClassName);
  return recv_addConstraint();
}

void AccumuloProxyClient::send_addConstraint(const std::string& sharedSecret, const std::string& tableName, const std::string& constraintClassName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("addConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_addConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.constraintClassName = &constraintClassName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

int32_t AccumuloProxyClient::recv_addConstraint()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("addConstraint") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  int32_t _return;
  AccumuloProxy_addConstraint_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addConstraint failed: unknown result");
}

void AccumuloProxyClient::addSplits(const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & splits)
{
  send_addSplits(sharedSecret, tableName, splits);
  recv_addSplits();
}

void AccumuloProxyClient::send_addSplits(const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & splits)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("addSplits", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_addSplits_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.splits = &splits;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_addSplits()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("addSplits") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_addSplits_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::attachIterator(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  send_attachIterator(sharedSecret, tableName, setting, scopes);
  recv_attachIterator();
}

void AccumuloProxyClient::send_attachIterator(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("attachIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_attachIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_attachIterator()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("attachIterator") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_attachIterator_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::checkIteratorConflicts(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  send_checkIteratorConflicts(sharedSecret, tableName, setting, scopes);
  recv_checkIteratorConflicts();
}

void AccumuloProxyClient::send_checkIteratorConflicts(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("checkIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_checkIteratorConflicts_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_checkIteratorConflicts()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("checkIteratorConflicts") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_checkIteratorConflicts_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::clearLocatorCache(const std::string& sharedSecret, const std::string& tableName)
{
  send_clearLocatorCache(sharedSecret, tableName);
  recv_clearLocatorCache();
}

void AccumuloProxyClient::send_clearLocatorCache(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("clearLocatorCache", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_clearLocatorCache_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_clearLocatorCache()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("clearLocatorCache") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_clearLocatorCache_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  return;
}

void AccumuloProxyClient::cloneTable(const std::string& sharedSecret, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude)
{
  send_cloneTable(sharedSecret, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
  recv_cloneTable();
}

void AccumuloProxyClient::send_cloneTable(const std::string& sharedSecret, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("cloneTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_cloneTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.newTableName = &newTableName;
  args.flush = &flush;
  args.propertiesToSet = &propertiesToSet;
  args.propertiesToExclude = &propertiesToExclude;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_cloneTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("cloneTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_cloneTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  if (result.__isset.ouch4) {
    throw result.ouch4;
  }
  return;
}

void AccumuloProxyClient::compactTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const PluginConfig& selectorConfig, const PluginConfig& configurerConfig)
{
  send_compactTable(sharedSecret, tableName, startRow, endRow, iterators, flush, wait, selectorConfig, configurerConfig);
  recv_compactTable();
}

void AccumuloProxyClient::send_compactTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const PluginConfig& selectorConfig, const PluginConfig& configurerConfig)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("compactTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_compactTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.iterators = &iterators;
  args.flush = &flush;
  args.wait = &wait;
  args.selectorConfig = &selectorConfig;
  args.configurerConfig = &configurerConfig;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_compactTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("compactTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_compactTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::cancelCompaction(const std::string& sharedSecret, const std::string& tableName)
{
  send_cancelCompaction(sharedSecret, tableName);
  recv_cancelCompaction();
}

void AccumuloProxyClient::send_cancelCompaction(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("cancelCompaction", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_cancelCompaction_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_cancelCompaction()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("cancelCompaction") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_cancelCompaction_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::createTable(const std::string& sharedSecret, const std::string& tableName, const bool versioningIter, const TimeType::type type)
{
  send_createTable(sharedSecret, tableName, versioningIter, type);
  recv_createTable();
}

void AccumuloProxyClient::send_createTable(const std::string& sharedSecret, const std::string& tableName, const bool versioningIter, const TimeType::type type)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.versioningIter = &versioningIter;
  args.type = &type;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::deleteTable(const std::string& sharedSecret, const std::string& tableName)
{
  send_deleteTable(sharedSecret, tableName);
  recv_deleteTable();
}

void AccumuloProxyClient::send_deleteTable(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("deleteTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_deleteTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_deleteTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("deleteTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_deleteTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::deleteRows(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  send_deleteRows(sharedSecret, tableName, startRow, endRow);
  recv_deleteRows();
}

void AccumuloProxyClient::send_deleteRows(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("deleteRows", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_deleteRows_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_deleteRows()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("deleteRows") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_deleteRows_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::exportTable(const std::string& sharedSecret, const std::string& tableName, const std::string& exportDir)
{
  send_exportTable(sharedSecret, tableName, exportDir);
  recv_exportTable();
}

void AccumuloProxyClient::send_exportTable(const std::string& sharedSecret, const std::string& tableName, const std::string& exportDir)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("exportTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_exportTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.exportDir = &exportDir;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_exportTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("exportTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_exportTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::flushTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait)
{
  send_flushTable(sharedSecret, tableName, startRow, endRow, wait);
  recv_flushTable();
}

void AccumuloProxyClient::send_flushTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("flushTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_flushTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.wait = &wait;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_flushTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("flushTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_flushTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::getDiskUsage(std::vector<DiskUsage> & _return, const std::string& sharedSecret, const std::set<std::string> & tables)
{
  send_getDiskUsage(sharedSecret, tables);
  recv_getDiskUsage(_return);
}

void AccumuloProxyClient::send_getDiskUsage(const std::string& sharedSecret, const std::set<std::string> & tables)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getDiskUsage", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getDiskUsage_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tables = &tables;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getDiskUsage(std::vector<DiskUsage> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getDiskUsage") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getDiskUsage_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getDiskUsage failed: unknown result");
}

void AccumuloProxyClient::getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& sharedSecret, const std::string& tableName)
{
  send_getLocalityGroups(sharedSecret, tableName);
  recv_getLocalityGroups(_return);
}

void AccumuloProxyClient::send_getLocalityGroups(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getLocalityGroups", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getLocalityGroups_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getLocalityGroups(std::map<std::string, std::set<std::string> > & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getLocalityGroups") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getLocalityGroups_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getLocalityGroups failed: unknown result");
}

void AccumuloProxyClient::getIteratorSetting(IteratorSetting& _return, const std::string& sharedSecret, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope)
{
  send_getIteratorSetting(sharedSecret, tableName, iteratorName, scope);
  recv_getIteratorSetting(_return);
}

void AccumuloProxyClient::send_getIteratorSetting(const std::string& sharedSecret, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getIteratorSetting_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.iteratorName = &iteratorName;
  args.scope = &scope;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getIteratorSetting(IteratorSetting& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getIteratorSetting") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getIteratorSetting_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getIteratorSetting failed: unknown result");
}

void AccumuloProxyClient::getMaxRow(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive)
{
  send_getMaxRow(sharedSecret, tableName, auths, startRow, startInclusive, endRow, endInclusive);
  recv_getMaxRow(_return);
}

void AccumuloProxyClient::send_getMaxRow(const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getMaxRow", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getMaxRow_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.auths = &auths;
  args.startRow = &startRow;
  args.startInclusive = &startInclusive;
  args.endRow = &endRow;
  args.endInclusive = &endInclusive;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getMaxRow(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getMaxRow") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getMaxRow_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getMaxRow failed: unknown result");
}

void AccumuloProxyClient::getTableProperties(std::map<std::string, std::string> & _return, const std::string& sharedSecret, const std::string& tableName)
{
  send_getTableProperties(sharedSecret, tableName);
  recv_getTableProperties(_return);
}

void AccumuloProxyClient::send_getTableProperties(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getTableProperties", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getTableProperties_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getTableProperties(std::map<std::string, std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getTableProperties") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getTableProperties_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getTableProperties failed: unknown result");
}

void AccumuloProxyClient::importDirectory(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime)
{
  send_importDirectory(sharedSecret, tableName, importDir, failureDir, setTime);
  recv_importDirectory();
}

void AccumuloProxyClient::send_importDirectory(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("importDirectory", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_importDirectory_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.importDir = &importDir;
  args.failureDir = &failureDir;
  args.setTime = &setTime;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_importDirectory()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("importDirectory") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_importDirectory_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  if (result.__isset.ouch4) {
    throw result.ouch4;
  }
  return;
}

void AccumuloProxyClient::importTable(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir)
{
  send_importTable(sharedSecret, tableName, importDir);
  recv_importTable();
}

void AccumuloProxyClient::send_importTable(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("importTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_importTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.importDir = &importDir;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_importTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("importTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_importTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::listSplits(std::vector<std::string> & _return, const std::string& sharedSecret, const std::string& tableName, const int32_t maxSplits)
{
  send_listSplits(sharedSecret, tableName, maxSplits);
  recv_listSplits(_return);
}

void AccumuloProxyClient::send_listSplits(const std::string& sharedSecret, const std::string& tableName, const int32_t maxSplits)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listSplits", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listSplits_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.maxSplits = &maxSplits;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listSplits(std::vector<std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listSplits") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listSplits_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listSplits failed: unknown result");
}

void AccumuloProxyClient::listTables(std::set<std::string> & _return, const std::string& sharedSecret)
{
  send_listTables(sharedSecret);
  recv_listTables(_return);
}

void AccumuloProxyClient::send_listTables(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listTables", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listTables_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listTables(std::set<std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listTables") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listTables_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listTables failed: unknown result");
}

void AccumuloProxyClient::listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& sharedSecret, const std::string& tableName)
{
  send_listIterators(sharedSecret, tableName);
  recv_listIterators(_return);
}

void AccumuloProxyClient::send_listIterators(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listIterators", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listIterators_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listIterators") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listIterators_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listIterators failed: unknown result");
}

void AccumuloProxyClient::listConstraints(std::map<std::string, int32_t> & _return, const std::string& sharedSecret, const std::string& tableName)
{
  send_listConstraints(sharedSecret, tableName);
  recv_listConstraints(_return);
}

void AccumuloProxyClient::send_listConstraints(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listConstraints", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listConstraints_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listConstraints(std::map<std::string, int32_t> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listConstraints") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listConstraints_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listConstraints failed: unknown result");
}

void AccumuloProxyClient::mergeTablets(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  send_mergeTablets(sharedSecret, tableName, startRow, endRow);
  recv_mergeTablets();
}

void AccumuloProxyClient::send_mergeTablets(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("mergeTablets", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_mergeTablets_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_mergeTablets()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("mergeTablets") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_mergeTablets_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::offlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  send_offlineTable(sharedSecret, tableName, wait);
  recv_offlineTable();
}

void AccumuloProxyClient::send_offlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("offlineTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_offlineTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.wait = &wait;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_offlineTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("offlineTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_offlineTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::onlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  send_onlineTable(sharedSecret, tableName, wait);
  recv_onlineTable();
}

void AccumuloProxyClient::send_onlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("onlineTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_onlineTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.wait = &wait;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_onlineTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("onlineTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_onlineTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::removeConstraint(const std::string& sharedSecret, const std::string& tableName, const int32_t constraint)
{
  send_removeConstraint(sharedSecret, tableName, constraint);
  recv_removeConstraint();
}

void AccumuloProxyClient::send_removeConstraint(const std::string& sharedSecret, const std::string& tableName, const int32_t constraint)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.constraint = &constraint;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeConstraint()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeConstraint") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeConstraint_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::removeIterator(const std::string& sharedSecret, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes)
{
  send_removeIterator(sharedSecret, tableName, iterName, scopes);
  recv_removeIterator();
}

void AccumuloProxyClient::send_removeIterator(const std::string& sharedSecret, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.iterName = &iterName;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeIterator()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeIterator") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeIterator_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::removeTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property)
{
  send_removeTableProperty(sharedSecret, tableName, property);
  recv_removeTableProperty();
}

void AccumuloProxyClient::send_removeTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeTableProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeTableProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.property = &property;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeTableProperty()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeTableProperty") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeTableProperty_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::renameTable(const std::string& sharedSecret, const std::string& oldTableName, const std::string& newTableName)
{
  send_renameTable(sharedSecret, oldTableName, newTableName);
  recv_renameTable();
}

void AccumuloProxyClient::send_renameTable(const std::string& sharedSecret, const std::string& oldTableName, const std::string& newTableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("renameTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_renameTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.oldTableName = &oldTableName;
  args.newTableName = &newTableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_renameTable()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("renameTable") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_renameTable_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  if (result.__isset.ouch4) {
    throw result.ouch4;
  }
  return;
}

void AccumuloProxyClient::setLocalityGroups(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups)
{
  send_setLocalityGroups(sharedSecret, tableName, groups);
  recv_setLocalityGroups();
}

void AccumuloProxyClient::send_setLocalityGroups(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("setLocalityGroups", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setLocalityGroups_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.groups = &groups;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_setLocalityGroups()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("setLocalityGroups") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_setLocalityGroups_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::setTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property, const std::string& value)
{
  send_setTableProperty(sharedSecret, tableName, property, value);
  recv_setTableProperty();
}

void AccumuloProxyClient::send_setTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property, const std::string& value)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("setTableProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setTableProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.property = &property;
  args.value = &value;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_setTableProperty()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("setTableProperty") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_setTableProperty_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::splitRangeByTablets(std::set<Range> & _return, const std::string& sharedSecret, const std::string& tableName, const Range& range, const int32_t maxSplits)
{
  send_splitRangeByTablets(sharedSecret, tableName, range, maxSplits);
  recv_splitRangeByTablets(_return);
}

void AccumuloProxyClient::send_splitRangeByTablets(const std::string& sharedSecret, const std::string& tableName, const Range& range, const int32_t maxSplits)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("splitRangeByTablets", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_splitRangeByTablets_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.range = &range;
  args.maxSplits = &maxSplits;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_splitRangeByTablets(std::set<Range> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("splitRangeByTablets") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_splitRangeByTablets_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "splitRangeByTablets failed: unknown result");
}

bool AccumuloProxyClient::tableExists(const std::string& sharedSecret, const std::string& tableName)
{
  send_tableExists(sharedSecret, tableName);
  return recv_tableExists();
}

void AccumuloProxyClient::send_tableExists(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("tableExists", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_tableExists_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_tableExists()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("tableExists") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_tableExists_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "tableExists failed: unknown result");
}

void AccumuloProxyClient::tableIdMap(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  send_tableIdMap(sharedSecret);
  recv_tableIdMap(_return);
}

void AccumuloProxyClient::send_tableIdMap(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("tableIdMap", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_tableIdMap_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_tableIdMap(std::map<std::string, std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("tableIdMap") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_tableIdMap_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "tableIdMap failed: unknown result");
}

bool AccumuloProxyClient::testTableClassLoad(const std::string& sharedSecret, const std::string& tableName, const std::string& className, const std::string& asTypeName)
{
  send_testTableClassLoad(sharedSecret, tableName, className, asTypeName);
  return recv_testTableClassLoad();
}

void AccumuloProxyClient::send_testTableClassLoad(const std::string& sharedSecret, const std::string& tableName, const std::string& className, const std::string& asTypeName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("testTableClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_testTableClassLoad_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.className = &className;
  args.asTypeName = &asTypeName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_testTableClassLoad()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("testTableClassLoad") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_testTableClassLoad_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testTableClassLoad failed: unknown result");
}

void AccumuloProxyClient::pingTabletServer(const std::string& sharedSecret, const std::string& tserver)
{
  send_pingTabletServer(sharedSecret, tserver);
  recv_pingTabletServer();
}

void AccumuloProxyClient::send_pingTabletServer(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("pingTabletServer", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_pingTabletServer_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tserver = &tserver;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_pingTabletServer()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("pingTabletServer") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_pingTabletServer_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::getActiveScans(std::vector<ActiveScan> & _return, const std::string& sharedSecret, const std::string& tserver)
{
  send_getActiveScans(sharedSecret, tserver);
  recv_getActiveScans(_return);
}

void AccumuloProxyClient::send_getActiveScans(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getActiveScans", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getActiveScans_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tserver = &tserver;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getActiveScans(std::vector<ActiveScan> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getActiveScans") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getActiveScans_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getActiveScans failed: unknown result");
}

void AccumuloProxyClient::getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& sharedSecret, const std::string& tserver)
{
  send_getActiveCompactions(sharedSecret, tserver);
  recv_getActiveCompactions(_return);
}

void AccumuloProxyClient::send_getActiveCompactions(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getActiveCompactions", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getActiveCompactions_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tserver = &tserver;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getActiveCompactions(std::vector<ActiveCompaction> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getActiveCompactions") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getActiveCompactions_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getActiveCompactions failed: unknown result");
}

void AccumuloProxyClient::getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  send_getSiteConfiguration(sharedSecret);
  recv_getSiteConfiguration(_return);
}

void AccumuloProxyClient::send_getSiteConfiguration(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getSiteConfiguration", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getSiteConfiguration_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getSiteConfiguration(std::map<std::string, std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getSiteConfiguration") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getSiteConfiguration_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSiteConfiguration failed: unknown result");
}

void AccumuloProxyClient::getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  send_getSystemConfiguration(sharedSecret);
  recv_getSystemConfiguration(_return);
}

void AccumuloProxyClient::send_getSystemConfiguration(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getSystemConfiguration", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getSystemConfiguration_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getSystemConfiguration(std::map<std::string, std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getSystemConfiguration") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getSystemConfiguration_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSystemConfiguration failed: unknown result");
}

void AccumuloProxyClient::getTabletServers(std::vector<std::string> & _return, const std::string& sharedSecret)
{
  send_getTabletServers(sharedSecret);
  recv_getTabletServers(_return);
}

void AccumuloProxyClient::send_getTabletServers(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getTabletServers", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getTabletServers_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getTabletServers(std::vector<std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getTabletServers") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getTabletServers_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getTabletServers failed: unknown result");
}

void AccumuloProxyClient::removeProperty(const std::string& sharedSecret, const std::string& property)
{
  send_removeProperty(sharedSecret, property);
  recv_removeProperty();
}

void AccumuloProxyClient::send_removeProperty(const std::string& sharedSecret, const std::string& property)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.property = &property;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeProperty()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeProperty") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeProperty_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::setProperty(const std::string& sharedSecret, const std::string& property, const std::string& value)
{
  send_setProperty(sharedSecret, property, value);
  recv_setProperty();
}

void AccumuloProxyClient::send_setProperty(const std::string& sharedSecret, const std::string& property, const std::string& value)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("setProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.property = &property;
  args.value = &value;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_setProperty()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("setProperty") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_setProperty_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

bool AccumuloProxyClient::testClassLoad(const std::string& sharedSecret, const std::string& className, const std::string& asTypeName)
{
  send_testClassLoad(sharedSecret, className, asTypeName);
  return recv_testClassLoad();
}

void AccumuloProxyClient::send_testClassLoad(const std::string& sharedSecret, const std::string& className, const std::string& asTypeName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("testClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_testClassLoad_pargs args;
  args.sharedSecret = &sharedSecret;
  args.className = &className;
  args.asTypeName = &asTypeName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_testClassLoad()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("testClassLoad") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_testClassLoad_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testClassLoad failed: unknown result");
}

bool AccumuloProxyClient::authenticateUser(const std::string& sharedSecret, const std::string& user, const std::map<std::string, std::string> & properties)
{
  send_authenticateUser(sharedSecret, user, properties);
  return recv_authenticateUser();
}

void AccumuloProxyClient::send_authenticateUser(const std::string& sharedSecret, const std::string& user, const std::map<std::string, std::string> & properties)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("authenticateUser", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_authenticateUser_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.properties = &properties;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_authenticateUser()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("authenticateUser") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_authenticateUser_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "authenticateUser failed: unknown result");
}

void AccumuloProxyClient::changeUserAuthorizations(const std::string& sharedSecret, const std::string& user, const std::set<std::string> & authorizations)
{
  send_changeUserAuthorizations(sharedSecret, user, authorizations);
  recv_changeUserAuthorizations();
}

void AccumuloProxyClient::send_changeUserAuthorizations(const std::string& sharedSecret, const std::string& user, const std::set<std::string> & authorizations)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("changeUserAuthorizations", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_changeUserAuthorizations_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.authorizations = &authorizations;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_changeUserAuthorizations()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("changeUserAuthorizations") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_changeUserAuthorizations_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::changeLocalUserPassword(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  send_changeLocalUserPassword(sharedSecret, user, password);
  recv_changeLocalUserPassword();
}

void AccumuloProxyClient::send_changeLocalUserPassword(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("changeLocalUserPassword", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_changeLocalUserPassword_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.password = &password;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_changeLocalUserPassword()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("changeLocalUserPassword") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_changeLocalUserPassword_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::createLocalUser(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  send_createLocalUser(sharedSecret, user, password);
  recv_createLocalUser();
}

void AccumuloProxyClient::send_createLocalUser(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createLocalUser", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createLocalUser_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.password = &password;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createLocalUser()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createLocalUser") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createLocalUser_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::dropLocalUser(const std::string& sharedSecret, const std::string& user)
{
  send_dropLocalUser(sharedSecret, user);
  recv_dropLocalUser();
}

void AccumuloProxyClient::send_dropLocalUser(const std::string& sharedSecret, const std::string& user)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("dropLocalUser", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_dropLocalUser_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_dropLocalUser()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("dropLocalUser") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_dropLocalUser_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::getUserAuthorizations(std::vector<std::string> & _return, const std::string& sharedSecret, const std::string& user)
{
  send_getUserAuthorizations(sharedSecret, user);
  recv_getUserAuthorizations(_return);
}

void AccumuloProxyClient::send_getUserAuthorizations(const std::string& sharedSecret, const std::string& user)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getUserAuthorizations", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getUserAuthorizations_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getUserAuthorizations(std::vector<std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getUserAuthorizations") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getUserAuthorizations_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getUserAuthorizations failed: unknown result");
}

void AccumuloProxyClient::grantSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  send_grantSystemPermission(sharedSecret, user, perm);
  recv_grantSystemPermission();
}

void AccumuloProxyClient::send_grantSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("grantSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_grantSystemPermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_grantSystemPermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("grantSystemPermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_grantSystemPermission_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::grantTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  send_grantTablePermission(sharedSecret, user, table, perm);
  recv_grantTablePermission();
}

void AccumuloProxyClient::send_grantTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("grantTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_grantTablePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.table = &table;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_grantTablePermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("grantTablePermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_grantTablePermission_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

bool AccumuloProxyClient::hasSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  send_hasSystemPermission(sharedSecret, user, perm);
  return recv_hasSystemPermission();
}

void AccumuloProxyClient::send_hasSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("hasSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasSystemPermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_hasSystemPermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("hasSystemPermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_hasSystemPermission_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasSystemPermission failed: unknown result");
}

bool AccumuloProxyClient::hasTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  send_hasTablePermission(sharedSecret, user, table, perm);
  return recv_hasTablePermission();
}

void AccumuloProxyClient::send_hasTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("hasTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasTablePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.table = &table;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_hasTablePermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("hasTablePermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_hasTablePermission_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasTablePermission failed: unknown result");
}

void AccumuloProxyClient::listLocalUsers(std::set<std::string> & _return, const std::string& sharedSecret)
{
  send_listLocalUsers(sharedSecret);
  recv_listLocalUsers(_return);
}

void AccumuloProxyClient::send_listLocalUsers(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listLocalUsers", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listLocalUsers_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listLocalUsers(std::set<std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listLocalUsers") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listLocalUsers_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listLocalUsers failed: unknown result");
}

void AccumuloProxyClient::revokeSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  send_revokeSystemPermission(sharedSecret, user, perm);
  recv_revokeSystemPermission();
}

void AccumuloProxyClient::send_revokeSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("revokeSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_revokeSystemPermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_revokeSystemPermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("revokeSystemPermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_revokeSystemPermission_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::revokeTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  send_revokeTablePermission(sharedSecret, user, table, perm);
  recv_revokeTablePermission();
}

void AccumuloProxyClient::send_revokeTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("revokeTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_revokeTablePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.table = &table;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_revokeTablePermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("revokeTablePermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_revokeTablePermission_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::grantNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  send_grantNamespacePermission(sharedSecret, user, namespaceName, perm);
  recv_grantNamespacePermission();
}

void AccumuloProxyClient::send_grantNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_grantNamespacePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.namespaceName = &namespaceName;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_grantNamespacePermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("grantNamespacePermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_grantNamespacePermission_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

bool AccumuloProxyClient::hasNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  send_hasNamespacePermission(sharedSecret, user, namespaceName, perm);
  return recv_hasNamespacePermission();
}

void AccumuloProxyClient::send_hasNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasNamespacePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.namespaceName = &namespaceName;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_hasNamespacePermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("hasNamespacePermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_hasNamespacePermission_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNamespacePermission failed: unknown result");
}

void AccumuloProxyClient::revokeNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  send_revokeNamespacePermission(sharedSecret, user, namespaceName, perm);
  recv_revokeNamespacePermission();
}

void AccumuloProxyClient::send_revokeNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_revokeNamespacePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.namespaceName = &namespaceName;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_revokeNamespacePermission()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("revokeNamespacePermission") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_revokeNamespacePermission_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::createBatchScanner(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const BatchScanOptions& options)
{
  send_createBatchScanner(sharedSecret, tableName, options);
  recv_createBatchScanner(_return);
}

void AccumuloProxyClient::send_createBatchScanner(const std::string& sharedSecret, const std::string& tableName, const BatchScanOptions& options)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createBatchScanner", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createBatchScanner_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.options = &options;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createBatchScanner(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createBatchScanner") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createBatchScanner_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createBatchScanner failed: unknown result");
}

void AccumuloProxyClient::createScanner(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const ScanOptions& options)
{
  send_createScanner(sharedSecret, tableName, options);
  recv_createScanner(_return);
}

void AccumuloProxyClient::send_createScanner(const std::string& sharedSecret, const std::string& tableName, const ScanOptions& options)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createScanner", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createScanner_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.options = &options;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createScanner(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createScanner") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createScanner_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createScanner failed: unknown result");
}

bool AccumuloProxyClient::hasNext(const std::string& scanner)
{
  send_hasNext(scanner);
  return recv_hasNext();
}

void AccumuloProxyClient::send_hasNext(const std::string& scanner)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("hasNext", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasNext_pargs args;
  args.scanner = &scanner;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_hasNext()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("hasNext") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_hasNext_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNext failed: unknown result");
}

void AccumuloProxyClient::nextEntry(KeyValueAndPeek& _return, const std::string& scanner)
{
  send_nextEntry(scanner);
  recv_nextEntry(_return);
}

void AccumuloProxyClient::send_nextEntry(const std::string& scanner)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("nextEntry", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_nextEntry_pargs args;
  args.scanner = &scanner;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_nextEntry(KeyValueAndPeek& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("nextEntry") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_nextEntry_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "nextEntry failed: unknown result");
}

void AccumuloProxyClient::nextK(ScanResult& _return, const std::string& scanner, const int32_t k)
{
  send_nextK(scanner, k);
  recv_nextK(_return);
}

void AccumuloProxyClient::send_nextK(const std::string& scanner, const int32_t k)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("nextK", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_nextK_pargs args;
  args.scanner = &scanner;
  args.k = &k;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_nextK(ScanResult& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("nextK") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_nextK_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "nextK failed: unknown result");
}

void AccumuloProxyClient::closeScanner(const std::string& scanner)
{
  send_closeScanner(scanner);
  recv_closeScanner();
}

void AccumuloProxyClient::send_closeScanner(const std::string& scanner)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("closeScanner", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_closeScanner_pargs args;
  args.scanner = &scanner;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_closeScanner()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("closeScanner") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_closeScanner_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  return;
}

void AccumuloProxyClient::updateAndFlush(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  send_updateAndFlush(sharedSecret, tableName, cells);
  recv_updateAndFlush();
}

void AccumuloProxyClient::send_updateAndFlush(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("updateAndFlush", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_updateAndFlush_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.cells = &cells;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_updateAndFlush()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("updateAndFlush") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_updateAndFlush_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.outch1) {
    throw result.outch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  if (result.__isset.ouch4) {
    throw result.ouch4;
  }
  return;
}

void AccumuloProxyClient::createWriter(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const WriterOptions& opts)
{
  send_createWriter(sharedSecret, tableName, opts);
  recv_createWriter(_return);
}

void AccumuloProxyClient::send_createWriter(const std::string& sharedSecret, const std::string& tableName, const WriterOptions& opts)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createWriter_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.opts = &opts;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createWriter(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createWriter") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createWriter_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.outch1) {
    throw result.outch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createWriter failed: unknown result");
}

void AccumuloProxyClient::update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  send_update(writer, cells);
}

void AccumuloProxyClient::send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("update", ::apache::thrift::protocol::T_ONEWAY, cseqid);

  AccumuloProxy_update_pargs args;
  args.writer = &writer;
  args.cells = &cells;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::flush(const std::string& writer)
{
  send_flush(writer);
  recv_flush();
}

void AccumuloProxyClient::send_flush(const std::string& writer)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("flush", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_flush_pargs args;
  args.writer = &writer;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_flush()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("flush") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_flush_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

void AccumuloProxyClient::closeWriter(const std::string& writer)
{
  send_closeWriter(writer);
  recv_closeWriter();
}

void AccumuloProxyClient::send_closeWriter(const std::string& writer)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("closeWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_closeWriter_pargs args;
  args.writer = &writer;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_closeWriter()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("closeWriter") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_closeWriter_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  return;
}

ConditionalStatus::type AccumuloProxyClient::updateRowConditionally(const std::string& sharedSecret, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates)
{
  send_updateRowConditionally(sharedSecret, tableName, row, updates);
  return recv_updateRowConditionally();
}

void AccumuloProxyClient::send_updateRowConditionally(const std::string& sharedSecret, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("updateRowConditionally", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_updateRowConditionally_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.row = &row;
  args.updates = &updates;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

ConditionalStatus::type AccumuloProxyClient::recv_updateRowConditionally()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("updateRowConditionally") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  ConditionalStatus::type _return;
  AccumuloProxy_updateRowConditionally_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "updateRowConditionally failed: unknown result");
}

void AccumuloProxyClient::createConditionalWriter(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const ConditionalWriterOptions& options)
{
  send_createConditionalWriter(sharedSecret, tableName, options);
  recv_createConditionalWriter(_return);
}

void AccumuloProxyClient::send_createConditionalWriter(const std::string& sharedSecret, const std::string& tableName, const ConditionalWriterOptions& options)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createConditionalWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createConditionalWriter_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.options = &options;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createConditionalWriter(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createConditionalWriter") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createConditionalWriter_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createConditionalWriter failed: unknown result");
}

void AccumuloProxyClient::updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates)
{
  send_updateRowsConditionally(conditionalWriter, updates);
  recv_updateRowsConditionally(_return);
}

void AccumuloProxyClient::send_updateRowsConditionally(const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("updateRowsConditionally", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_updateRowsConditionally_pargs args;
  args.conditionalWriter = &conditionalWriter;
  args.updates = &updates;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("updateRowsConditionally") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_updateRowsConditionally_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "updateRowsConditionally failed: unknown result");
}

void AccumuloProxyClient::closeConditionalWriter(const std::string& conditionalWriter)
{
  send_closeConditionalWriter(conditionalWriter);
  recv_closeConditionalWriter();
}

void AccumuloProxyClient::send_closeConditionalWriter(const std::string& conditionalWriter)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("closeConditionalWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_closeConditionalWriter_pargs args;
  args.conditionalWriter = &conditionalWriter;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_closeConditionalWriter()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("closeConditionalWriter") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_closeConditionalWriter_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  return;
}

void AccumuloProxyClient::getRowRange(Range& _return, const std::string& row)
{
  send_getRowRange(row);
  recv_getRowRange(_return);
}

void AccumuloProxyClient::send_getRowRange(const std::string& row)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getRowRange", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getRowRange_pargs args;
  args.row = &row;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getRowRange(Range& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getRowRange") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getRowRange_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getRowRange failed: unknown result");
}

void AccumuloProxyClient::getFollowing(Key& _return, const Key& key, const PartialKey::type part)
{
  send_getFollowing(key, part);
  recv_getFollowing(_return);
}

void AccumuloProxyClient::send_getFollowing(const Key& key, const PartialKey::type part)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getFollowing", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getFollowing_pargs args;
  args.key = &key;
  args.part = &part;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getFollowing(Key& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getFollowing") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getFollowing_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getFollowing failed: unknown result");
}

void AccumuloProxyClient::systemNamespace(std::string& _return)
{
  send_systemNamespace();
  recv_systemNamespace(_return);
}

void AccumuloProxyClient::send_systemNamespace()
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_systemNamespace_pargs args;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_systemNamespace(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("systemNamespace") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_systemNamespace_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "systemNamespace failed: unknown result");
}

void AccumuloProxyClient::defaultNamespace(std::string& _return)
{
  send_defaultNamespace();
  recv_defaultNamespace(_return);
}

void AccumuloProxyClient::send_defaultNamespace()
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_defaultNamespace_pargs args;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_defaultNamespace(std::string& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("defaultNamespace") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_defaultNamespace_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "defaultNamespace failed: unknown result");
}

void AccumuloProxyClient::listNamespaces(std::vector<std::string> & _return, const std::string& sharedSecret)
{
  send_listNamespaces(sharedSecret);
  recv_listNamespaces(_return);
}

void AccumuloProxyClient::send_listNamespaces(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listNamespaces_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listNamespaces(std::vector<std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listNamespaces") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listNamespaces_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaces failed: unknown result");
}

bool AccumuloProxyClient::namespaceExists(const std::string& sharedSecret, const std::string& namespaceName)
{
  send_namespaceExists(sharedSecret, namespaceName);
  return recv_namespaceExists();
}

void AccumuloProxyClient::send_namespaceExists(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_namespaceExists_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_namespaceExists()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("namespaceExists") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_namespaceExists_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceExists failed: unknown result");
}

void AccumuloProxyClient::createNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  send_createNamespace(sharedSecret, namespaceName);
  recv_createNamespace();
}

void AccumuloProxyClient::send_createNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createNamespace_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_createNamespace()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("createNamespace") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_createNamespace_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::deleteNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  send_deleteNamespace(sharedSecret, namespaceName);
  recv_deleteNamespace();
}

void AccumuloProxyClient::send_deleteNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_deleteNamespace_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_deleteNamespace()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("deleteNamespace") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_deleteNamespace_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  if (result.__isset.ouch4) {
    throw result.ouch4;
  }
  return;
}

void AccumuloProxyClient::renameNamespace(const std::string& sharedSecret, const std::string& oldNamespaceName, const std::string& newNamespaceName)
{
  send_renameNamespace(sharedSecret, oldNamespaceName, newNamespaceName);
  recv_renameNamespace();
}

void AccumuloProxyClient::send_renameNamespace(const std::string& sharedSecret, const std::string& oldNamespaceName, const std::string& newNamespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_renameNamespace_pargs args;
  args.sharedSecret = &sharedSecret;
  args.oldNamespaceName = &oldNamespaceName;
  args.newNamespaceName = &newNamespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_renameNamespace()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("renameNamespace") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_renameNamespace_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  if (result.__isset.ouch4) {
    throw result.ouch4;
  }
  return;
}

void AccumuloProxyClient::setNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property, const std::string& value)
{
  send_setNamespaceProperty(sharedSecret, namespaceName, property, value);
  recv_setNamespaceProperty();
}

void AccumuloProxyClient::send_setNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property, const std::string& value)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setNamespaceProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.property = &property;
  args.value = &value;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_setNamespaceProperty()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("setNamespaceProperty") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_setNamespaceProperty_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::removeNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property)
{
  send_removeNamespaceProperty(sharedSecret, namespaceName, property);
  recv_removeNamespaceProperty();
}

void AccumuloProxyClient::send_removeNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeNamespaceProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.property = &property;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeNamespaceProperty()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeNamespaceProperty") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeNamespaceProperty_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& sharedSecret, const std::string& namespaceName)
{
  send_getNamespaceProperties(sharedSecret, namespaceName);
  recv_getNamespaceProperties(_return);
}

void AccumuloProxyClient::send_getNamespaceProperties(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getNamespaceProperties_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getNamespaceProperties(std::map<std::string, std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getNamespaceProperties") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getNamespaceProperties_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceProperties failed: unknown result");
}

void AccumuloProxyClient::namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  send_namespaceIdMap(sharedSecret);
  recv_namespaceIdMap(_return);
}

void AccumuloProxyClient::send_namespaceIdMap(const std::string& sharedSecret)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_namespaceIdMap_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_namespaceIdMap(std::map<std::string, std::string> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("namespaceIdMap") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_namespaceIdMap_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceIdMap failed: unknown result");
}

void AccumuloProxyClient::attachNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  send_attachNamespaceIterator(sharedSecret, namespaceName, setting, scopes);
  recv_attachNamespaceIterator();
}

void AccumuloProxyClient::send_attachNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_attachNamespaceIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_attachNamespaceIterator()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("attachNamespaceIterator") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_attachNamespaceIterator_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::removeNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
{
  send_removeNamespaceIterator(sharedSecret, namespaceName, name, scopes);
  recv_removeNamespaceIterator();
}

void AccumuloProxyClient::send_removeNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeNamespaceIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.name = &name;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeNamespaceIterator()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeNamespaceIterator") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeNamespaceIterator_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
{
  send_getNamespaceIteratorSetting(sharedSecret, namespaceName, name, scope);
  recv_getNamespaceIteratorSetting(_return);
}

void AccumuloProxyClient::send_getNamespaceIteratorSetting(const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getNamespaceIteratorSetting_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.name = &name;
  args.scope = &scope;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_getNamespaceIteratorSetting(IteratorSetting& _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("getNamespaceIteratorSetting") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_getNamespaceIteratorSetting_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result");
}

void AccumuloProxyClient::listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& sharedSecret, const std::string& namespaceName)
{
  send_listNamespaceIterators(sharedSecret, namespaceName);
  recv_listNamespaceIterators(_return);
}

void AccumuloProxyClient::send_listNamespaceIterators(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listNamespaceIterators_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listNamespaceIterators") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listNamespaceIterators_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceIterators failed: unknown result");
}

void AccumuloProxyClient::checkNamespaceIteratorConflicts(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  send_checkNamespaceIteratorConflicts(sharedSecret, namespaceName, setting, scopes);
  recv_checkNamespaceIteratorConflicts();
}

void AccumuloProxyClient::send_checkNamespaceIteratorConflicts(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_checkNamespaceIteratorConflicts_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_checkNamespaceIteratorConflicts()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("checkNamespaceIteratorConflicts") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_checkNamespaceIteratorConflicts_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

int32_t AccumuloProxyClient::addNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const std::string& constraintClassName)
{
  send_addNamespaceConstraint(sharedSecret, namespaceName, constraintClassName);
  return recv_addNamespaceConstraint();
}

void AccumuloProxyClient::send_addNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const std::string& constraintClassName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_addNamespaceConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.constraintClassName = &constraintClassName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

int32_t AccumuloProxyClient::recv_addNamespaceConstraint()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("addNamespaceConstraint") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  int32_t _return;
  AccumuloProxy_addNamespaceConstraint_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addNamespaceConstraint failed: unknown result");
}

void AccumuloProxyClient::removeNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const int32_t id)
{
  send_removeNamespaceConstraint(sharedSecret, namespaceName, id);
  recv_removeNamespaceConstraint();
}

void AccumuloProxyClient::send_removeNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const int32_t id)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeNamespaceConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.id = &id;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_removeNamespaceConstraint()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("removeNamespaceConstraint") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_removeNamespaceConstraint_presult result;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  return;
}

void AccumuloProxyClient::listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& sharedSecret, const std::string& namespaceName)
{
  send_listNamespaceConstraints(sharedSecret, namespaceName);
  recv_listNamespaceConstraints(_return);
}

void AccumuloProxyClient::send_listNamespaceConstraints(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listNamespaceConstraints_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

void AccumuloProxyClient::recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("listNamespaceConstraints") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  AccumuloProxy_listNamespaceConstraints_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    // _return pointer has now been filled
    return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceConstraints failed: unknown result");
}

bool AccumuloProxyClient::testNamespaceClassLoad(const std::string& sharedSecret, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
{
  send_testNamespaceClassLoad(sharedSecret, namespaceName, className, asTypeName);
  return recv_testNamespaceClassLoad();
}

void AccumuloProxyClient::send_testNamespaceClassLoad(const std::string& sharedSecret, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
{
  int32_t cseqid = 0;
  oprot_->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_testNamespaceClassLoad_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.className = &className;
  args.asTypeName = &asTypeName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();
}

bool AccumuloProxyClient::recv_testNamespaceClassLoad()
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  iprot_->readMessageBegin(fname, mtype, rseqid);
  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
    ::apache::thrift::TApplicationException x;
    x.read(iprot_);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
    throw x;
  }
  if (mtype != ::apache::thrift::protocol::T_REPLY) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  if (fname.compare("testNamespaceClassLoad") != 0) {
    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
    iprot_->readMessageEnd();
    iprot_->getTransport()->readEnd();
  }
  bool _return;
  AccumuloProxy_testNamespaceClassLoad_presult result;
  result.success = &_return;
  result.read(iprot_);
  iprot_->readMessageEnd();
  iprot_->getTransport()->readEnd();

  if (result.__isset.success) {
    return _return;
  }
  if (result.__isset.ouch1) {
    throw result.ouch1;
  }
  if (result.__isset.ouch2) {
    throw result.ouch2;
  }
  if (result.__isset.ouch3) {
    throw result.ouch3;
  }
  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testNamespaceClassLoad failed: unknown result");
}

bool AccumuloProxyProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
  ProcessMap::iterator pfn;
  pfn = processMap_.find(fname);
  if (pfn == processMap_.end()) {
    iprot->skip(::apache::thrift::protocol::T_STRUCT);
    iprot->readMessageEnd();
    iprot->getTransport()->readEnd();
    ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
    oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return true;
  }
  (this->*(pfn->second))(seqid, iprot, oprot, callContext);
  return true;
}

void AccumuloProxyProcessor::process_addConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.addConstraint", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.addConstraint");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.addConstraint");
  }

  AccumuloProxy_addConstraint_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.addConstraint", bytes);
  }

  AccumuloProxy_addConstraint_result result;
  try {
    result.success = iface_->addConstraint(args.sharedSecret, args.tableName, args.constraintClassName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.addConstraint");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("addConstraint", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.addConstraint");
  }

  oprot->writeMessageBegin("addConstraint", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.addConstraint", bytes);
  }
}

void AccumuloProxyProcessor::process_addSplits(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.addSplits", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.addSplits");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.addSplits");
  }

  AccumuloProxy_addSplits_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.addSplits", bytes);
  }

  AccumuloProxy_addSplits_result result;
  try {
    iface_->addSplits(args.sharedSecret, args.tableName, args.splits);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.addSplits");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("addSplits", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.addSplits");
  }

  oprot->writeMessageBegin("addSplits", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.addSplits", bytes);
  }
}

void AccumuloProxyProcessor::process_attachIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.attachIterator", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.attachIterator");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.attachIterator");
  }

  AccumuloProxy_attachIterator_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.attachIterator", bytes);
  }

  AccumuloProxy_attachIterator_result result;
  try {
    iface_->attachIterator(args.sharedSecret, args.tableName, args.setting, args.scopes);
  } catch (AccumuloSecurityException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.attachIterator");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("attachIterator", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.attachIterator");
  }

  oprot->writeMessageBegin("attachIterator", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.attachIterator", bytes);
  }
}

void AccumuloProxyProcessor::process_checkIteratorConflicts(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.checkIteratorConflicts", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.checkIteratorConflicts");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.checkIteratorConflicts");
  }

  AccumuloProxy_checkIteratorConflicts_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.checkIteratorConflicts", bytes);
  }

  AccumuloProxy_checkIteratorConflicts_result result;
  try {
    iface_->checkIteratorConflicts(args.sharedSecret, args.tableName, args.setting, args.scopes);
  } catch (AccumuloSecurityException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.checkIteratorConflicts");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("checkIteratorConflicts", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.checkIteratorConflicts");
  }

  oprot->writeMessageBegin("checkIteratorConflicts", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.checkIteratorConflicts", bytes);
  }
}

void AccumuloProxyProcessor::process_clearLocatorCache(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.clearLocatorCache", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.clearLocatorCache");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.clearLocatorCache");
  }

  AccumuloProxy_clearLocatorCache_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.clearLocatorCache", bytes);
  }

  AccumuloProxy_clearLocatorCache_result result;
  try {
    iface_->clearLocatorCache(args.sharedSecret, args.tableName);
  } catch (TableNotFoundException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.clearLocatorCache");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("clearLocatorCache", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.clearLocatorCache");
  }

  oprot->writeMessageBegin("clearLocatorCache", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.clearLocatorCache", bytes);
  }
}

void AccumuloProxyProcessor::process_cloneTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.cloneTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.cloneTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.cloneTable");
  }

  AccumuloProxy_cloneTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.cloneTable", bytes);
  }

  AccumuloProxy_cloneTable_result result;
  try {
    iface_->cloneTable(args.sharedSecret, args.tableName, args.newTableName, args.flush, args.propertiesToSet, args.propertiesToExclude);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (TableExistsException &ouch4) {
    result.ouch4 = std::move(ouch4);
    result.__isset.ouch4 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.cloneTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("cloneTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.cloneTable");
  }

  oprot->writeMessageBegin("cloneTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.cloneTable", bytes);
  }
}

void AccumuloProxyProcessor::process_compactTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.compactTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.compactTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.compactTable");
  }

  AccumuloProxy_compactTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.compactTable", bytes);
  }

  AccumuloProxy_compactTable_result result;
  try {
    iface_->compactTable(args.sharedSecret, args.tableName, args.startRow, args.endRow, args.iterators, args.flush, args.wait, args.selectorConfig, args.configurerConfig);
  } catch (AccumuloSecurityException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (TableNotFoundException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (AccumuloException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.compactTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("compactTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.compactTable");
  }

  oprot->writeMessageBegin("compactTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.compactTable", bytes);
  }
}

void AccumuloProxyProcessor::process_cancelCompaction(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.cancelCompaction", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.cancelCompaction");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.cancelCompaction");
  }

  AccumuloProxy_cancelCompaction_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.cancelCompaction", bytes);
  }

  AccumuloProxy_cancelCompaction_result result;
  try {
    iface_->cancelCompaction(args.sharedSecret, args.tableName);
  } catch (AccumuloSecurityException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (TableNotFoundException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (AccumuloException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.cancelCompaction");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("cancelCompaction", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.cancelCompaction");
  }

  oprot->writeMessageBegin("cancelCompaction", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.cancelCompaction", bytes);
  }
}

void AccumuloProxyProcessor::process_createTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createTable");
  }

  AccumuloProxy_createTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createTable", bytes);
  }

  AccumuloProxy_createTable_result result;
  try {
    iface_->createTable(args.sharedSecret, args.tableName, args.versioningIter, args.type);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableExistsException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createTable");
  }

  oprot->writeMessageBegin("createTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createTable", bytes);
  }
}

void AccumuloProxyProcessor::process_deleteTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.deleteTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.deleteTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.deleteTable");
  }

  AccumuloProxy_deleteTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.deleteTable", bytes);
  }

  AccumuloProxy_deleteTable_result result;
  try {
    iface_->deleteTable(args.sharedSecret, args.tableName);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.deleteTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("deleteTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.deleteTable");
  }

  oprot->writeMessageBegin("deleteTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.deleteTable", bytes);
  }
}

void AccumuloProxyProcessor::process_deleteRows(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.deleteRows", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.deleteRows");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.deleteRows");
  }

  AccumuloProxy_deleteRows_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.deleteRows", bytes);
  }

  AccumuloProxy_deleteRows_result result;
  try {
    iface_->deleteRows(args.sharedSecret, args.tableName, args.startRow, args.endRow);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.deleteRows");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("deleteRows", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.deleteRows");
  }

  oprot->writeMessageBegin("deleteRows", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.deleteRows", bytes);
  }
}

void AccumuloProxyProcessor::process_exportTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.exportTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.exportTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.exportTable");
  }

  AccumuloProxy_exportTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.exportTable", bytes);
  }

  AccumuloProxy_exportTable_result result;
  try {
    iface_->exportTable(args.sharedSecret, args.tableName, args.exportDir);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.exportTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("exportTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.exportTable");
  }

  oprot->writeMessageBegin("exportTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.exportTable", bytes);
  }
}

void AccumuloProxyProcessor::process_flushTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.flushTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.flushTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.flushTable");
  }

  AccumuloProxy_flushTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.flushTable", bytes);
  }

  AccumuloProxy_flushTable_result result;
  try {
    iface_->flushTable(args.sharedSecret, args.tableName, args.startRow, args.endRow, args.wait);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.flushTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("flushTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.flushTable");
  }

  oprot->writeMessageBegin("flushTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.flushTable", bytes);
  }
}

void AccumuloProxyProcessor::process_getDiskUsage(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getDiskUsage", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getDiskUsage");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getDiskUsage");
  }

  AccumuloProxy_getDiskUsage_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getDiskUsage", bytes);
  }

  AccumuloProxy_getDiskUsage_result result;
  try {
    iface_->getDiskUsage(result.success, args.sharedSecret, args.tables);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getDiskUsage");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getDiskUsage", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getDiskUsage");
  }

  oprot->writeMessageBegin("getDiskUsage", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getDiskUsage", bytes);
  }
}

void AccumuloProxyProcessor::process_getLocalityGroups(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getLocalityGroups", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getLocalityGroups");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getLocalityGroups");
  }

  AccumuloProxy_getLocalityGroups_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getLocalityGroups", bytes);
  }

  AccumuloProxy_getLocalityGroups_result result;
  try {
    iface_->getLocalityGroups(result.success, args.sharedSecret, args.tableName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getLocalityGroups");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getLocalityGroups", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getLocalityGroups");
  }

  oprot->writeMessageBegin("getLocalityGroups", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getLocalityGroups", bytes);
  }
}

void AccumuloProxyProcessor::process_getIteratorSetting(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getIteratorSetting", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getIteratorSetting");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getIteratorSetting");
  }

  AccumuloProxy_getIteratorSetting_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getIteratorSetting", bytes);
  }

  AccumuloProxy_getIteratorSetting_result result;
  try {
    iface_->getIteratorSetting(result.success, args.sharedSecret, args.tableName, args.iteratorName, args.scope);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getIteratorSetting");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getIteratorSetting", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getIteratorSetting");
  }

  oprot->writeMessageBegin("getIteratorSetting", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getIteratorSetting", bytes);
  }
}

void AccumuloProxyProcessor::process_getMaxRow(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getMaxRow", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getMaxRow");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getMaxRow");
  }

  AccumuloProxy_getMaxRow_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getMaxRow", bytes);
  }

  AccumuloProxy_getMaxRow_result result;
  try {
    iface_->getMaxRow(result.success, args.sharedSecret, args.tableName, args.auths, args.startRow, args.startInclusive, args.endRow, args.endInclusive);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getMaxRow");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getMaxRow", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getMaxRow");
  }

  oprot->writeMessageBegin("getMaxRow", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getMaxRow", bytes);
  }
}

void AccumuloProxyProcessor::process_getTableProperties(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getTableProperties", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getTableProperties");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getTableProperties");
  }

  AccumuloProxy_getTableProperties_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getTableProperties", bytes);
  }

  AccumuloProxy_getTableProperties_result result;
  try {
    iface_->getTableProperties(result.success, args.sharedSecret, args.tableName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getTableProperties");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getTableProperties", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getTableProperties");
  }

  oprot->writeMessageBegin("getTableProperties", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getTableProperties", bytes);
  }
}

void AccumuloProxyProcessor::process_importDirectory(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.importDirectory", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.importDirectory");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.importDirectory");
  }

  AccumuloProxy_importDirectory_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.importDirectory", bytes);
  }

  AccumuloProxy_importDirectory_result result;
  try {
    iface_->importDirectory(args.sharedSecret, args.tableName, args.importDir, args.failureDir, args.setTime);
  } catch (TableNotFoundException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (AccumuloSecurityException &ouch4) {
    result.ouch4 = std::move(ouch4);
    result.__isset.ouch4 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.importDirectory");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("importDirectory", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.importDirectory");
  }

  oprot->writeMessageBegin("importDirectory", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.importDirectory", bytes);
  }
}

void AccumuloProxyProcessor::process_importTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.importTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.importTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.importTable");
  }

  AccumuloProxy_importTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.importTable", bytes);
  }

  AccumuloProxy_importTable_result result;
  try {
    iface_->importTable(args.sharedSecret, args.tableName, args.importDir);
  } catch (TableExistsException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (AccumuloSecurityException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.importTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("importTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.importTable");
  }

  oprot->writeMessageBegin("importTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.importTable", bytes);
  }
}

void AccumuloProxyProcessor::process_listSplits(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listSplits", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listSplits");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listSplits");
  }

  AccumuloProxy_listSplits_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listSplits", bytes);
  }

  AccumuloProxy_listSplits_result result;
  try {
    iface_->listSplits(result.success, args.sharedSecret, args.tableName, args.maxSplits);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listSplits");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listSplits", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listSplits");
  }

  oprot->writeMessageBegin("listSplits", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listSplits", bytes);
  }
}

void AccumuloProxyProcessor::process_listTables(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listTables", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listTables");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listTables");
  }

  AccumuloProxy_listTables_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listTables", bytes);
  }

  AccumuloProxy_listTables_result result;
  try {
    iface_->listTables(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listTables");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listTables", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listTables");
  }

  oprot->writeMessageBegin("listTables", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listTables", bytes);
  }
}

void AccumuloProxyProcessor::process_listIterators(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listIterators", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listIterators");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listIterators");
  }

  AccumuloProxy_listIterators_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listIterators", bytes);
  }

  AccumuloProxy_listIterators_result result;
  try {
    iface_->listIterators(result.success, args.sharedSecret, args.tableName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listIterators");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listIterators", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listIterators");
  }

  oprot->writeMessageBegin("listIterators", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listIterators", bytes);
  }
}

void AccumuloProxyProcessor::process_listConstraints(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listConstraints", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listConstraints");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listConstraints");
  }

  AccumuloProxy_listConstraints_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listConstraints", bytes);
  }

  AccumuloProxy_listConstraints_result result;
  try {
    iface_->listConstraints(result.success, args.sharedSecret, args.tableName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listConstraints");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listConstraints", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listConstraints");
  }

  oprot->writeMessageBegin("listConstraints", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listConstraints", bytes);
  }
}

void AccumuloProxyProcessor::process_mergeTablets(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.mergeTablets", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.mergeTablets");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.mergeTablets");
  }

  AccumuloProxy_mergeTablets_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.mergeTablets", bytes);
  }

  AccumuloProxy_mergeTablets_result result;
  try {
    iface_->mergeTablets(args.sharedSecret, args.tableName, args.startRow, args.endRow);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.mergeTablets");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("mergeTablets", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.mergeTablets");
  }

  oprot->writeMessageBegin("mergeTablets", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.mergeTablets", bytes);
  }
}

void AccumuloProxyProcessor::process_offlineTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.offlineTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.offlineTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.offlineTable");
  }

  AccumuloProxy_offlineTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.offlineTable", bytes);
  }

  AccumuloProxy_offlineTable_result result;
  try {
    iface_->offlineTable(args.sharedSecret, args.tableName, args.wait);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.offlineTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("offlineTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.offlineTable");
  }

  oprot->writeMessageBegin("offlineTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.offlineTable", bytes);
  }
}

void AccumuloProxyProcessor::process_onlineTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.onlineTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.onlineTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.onlineTable");
  }

  AccumuloProxy_onlineTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.onlineTable", bytes);
  }

  AccumuloProxy_onlineTable_result result;
  try {
    iface_->onlineTable(args.sharedSecret, args.tableName, args.wait);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.onlineTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("onlineTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.onlineTable");
  }

  oprot->writeMessageBegin("onlineTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.onlineTable", bytes);
  }
}

void AccumuloProxyProcessor::process_removeConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeConstraint", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeConstraint");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeConstraint");
  }

  AccumuloProxy_removeConstraint_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeConstraint", bytes);
  }

  AccumuloProxy_removeConstraint_result result;
  try {
    iface_->removeConstraint(args.sharedSecret, args.tableName, args.constraint);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeConstraint");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeConstraint", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeConstraint");
  }

  oprot->writeMessageBegin("removeConstraint", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeConstraint", bytes);
  }
}

void AccumuloProxyProcessor::process_removeIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeIterator", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeIterator");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeIterator");
  }

  AccumuloProxy_removeIterator_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeIterator", bytes);
  }

  AccumuloProxy_removeIterator_result result;
  try {
    iface_->removeIterator(args.sharedSecret, args.tableName, args.iterName, args.scopes);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeIterator");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeIterator", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeIterator");
  }

  oprot->writeMessageBegin("removeIterator", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeIterator", bytes);
  }
}

void AccumuloProxyProcessor::process_removeTableProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeTableProperty", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeTableProperty");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeTableProperty");
  }

  AccumuloProxy_removeTableProperty_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeTableProperty", bytes);
  }

  AccumuloProxy_removeTableProperty_result result;
  try {
    iface_->removeTableProperty(args.sharedSecret, args.tableName, args.property);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeTableProperty");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeTableProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeTableProperty");
  }

  oprot->writeMessageBegin("removeTableProperty", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeTableProperty", bytes);
  }
}

void AccumuloProxyProcessor::process_renameTable(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.renameTable", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.renameTable");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.renameTable");
  }

  AccumuloProxy_renameTable_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.renameTable", bytes);
  }

  AccumuloProxy_renameTable_result result;
  try {
    iface_->renameTable(args.sharedSecret, args.oldTableName, args.newTableName);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (TableExistsException &ouch4) {
    result.ouch4 = std::move(ouch4);
    result.__isset.ouch4 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.renameTable");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("renameTable", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.renameTable");
  }

  oprot->writeMessageBegin("renameTable", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.renameTable", bytes);
  }
}

void AccumuloProxyProcessor::process_setLocalityGroups(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.setLocalityGroups", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.setLocalityGroups");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.setLocalityGroups");
  }

  AccumuloProxy_setLocalityGroups_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.setLocalityGroups", bytes);
  }

  AccumuloProxy_setLocalityGroups_result result;
  try {
    iface_->setLocalityGroups(args.sharedSecret, args.tableName, args.groups);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.setLocalityGroups");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("setLocalityGroups", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.setLocalityGroups");
  }

  oprot->writeMessageBegin("setLocalityGroups", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.setLocalityGroups", bytes);
  }
}

void AccumuloProxyProcessor::process_setTableProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.setTableProperty", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.setTableProperty");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.setTableProperty");
  }

  AccumuloProxy_setTableProperty_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.setTableProperty", bytes);
  }

  AccumuloProxy_setTableProperty_result result;
  try {
    iface_->setTableProperty(args.sharedSecret, args.tableName, args.property, args.value);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.setTableProperty");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("setTableProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.setTableProperty");
  }

  oprot->writeMessageBegin("setTableProperty", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.setTableProperty", bytes);
  }
}

void AccumuloProxyProcessor::process_splitRangeByTablets(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.splitRangeByTablets", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.splitRangeByTablets");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.splitRangeByTablets");
  }

  AccumuloProxy_splitRangeByTablets_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.splitRangeByTablets", bytes);
  }

  AccumuloProxy_splitRangeByTablets_result result;
  try {
    iface_->splitRangeByTablets(result.success, args.sharedSecret, args.tableName, args.range, args.maxSplits);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.splitRangeByTablets");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("splitRangeByTablets", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.splitRangeByTablets");
  }

  oprot->writeMessageBegin("splitRangeByTablets", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.splitRangeByTablets", bytes);
  }
}

void AccumuloProxyProcessor::process_tableExists(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.tableExists", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.tableExists");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.tableExists");
  }

  AccumuloProxy_tableExists_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.tableExists", bytes);
  }

  AccumuloProxy_tableExists_result result;
  try {
    result.success = iface_->tableExists(args.sharedSecret, args.tableName);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.tableExists");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("tableExists", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.tableExists");
  }

  oprot->writeMessageBegin("tableExists", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.tableExists", bytes);
  }
}

void AccumuloProxyProcessor::process_tableIdMap(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.tableIdMap", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.tableIdMap");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.tableIdMap");
  }

  AccumuloProxy_tableIdMap_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.tableIdMap", bytes);
  }

  AccumuloProxy_tableIdMap_result result;
  try {
    iface_->tableIdMap(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.tableIdMap");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("tableIdMap", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.tableIdMap");
  }

  oprot->writeMessageBegin("tableIdMap", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.tableIdMap", bytes);
  }
}

void AccumuloProxyProcessor::process_testTableClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.testTableClassLoad", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.testTableClassLoad");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.testTableClassLoad");
  }

  AccumuloProxy_testTableClassLoad_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.testTableClassLoad", bytes);
  }

  AccumuloProxy_testTableClassLoad_result result;
  try {
    result.success = iface_->testTableClassLoad(args.sharedSecret, args.tableName, args.className, args.asTypeName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.testTableClassLoad");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("testTableClassLoad", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.testTableClassLoad");
  }

  oprot->writeMessageBegin("testTableClassLoad", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.testTableClassLoad", bytes);
  }
}

void AccumuloProxyProcessor::process_pingTabletServer(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.pingTabletServer", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.pingTabletServer");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.pingTabletServer");
  }

  AccumuloProxy_pingTabletServer_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.pingTabletServer", bytes);
  }

  AccumuloProxy_pingTabletServer_result result;
  try {
    iface_->pingTabletServer(args.sharedSecret, args.tserver);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.pingTabletServer");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("pingTabletServer", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.pingTabletServer");
  }

  oprot->writeMessageBegin("pingTabletServer", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.pingTabletServer", bytes);
  }
}

void AccumuloProxyProcessor::process_getActiveScans(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getActiveScans", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getActiveScans");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getActiveScans");
  }

  AccumuloProxy_getActiveScans_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getActiveScans", bytes);
  }

  AccumuloProxy_getActiveScans_result result;
  try {
    iface_->getActiveScans(result.success, args.sharedSecret, args.tserver);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getActiveScans");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getActiveScans", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getActiveScans");
  }

  oprot->writeMessageBegin("getActiveScans", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getActiveScans", bytes);
  }
}

void AccumuloProxyProcessor::process_getActiveCompactions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getActiveCompactions", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getActiveCompactions");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getActiveCompactions");
  }

  AccumuloProxy_getActiveCompactions_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getActiveCompactions", bytes);
  }

  AccumuloProxy_getActiveCompactions_result result;
  try {
    iface_->getActiveCompactions(result.success, args.sharedSecret, args.tserver);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getActiveCompactions");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getActiveCompactions", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getActiveCompactions");
  }

  oprot->writeMessageBegin("getActiveCompactions", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getActiveCompactions", bytes);
  }
}

void AccumuloProxyProcessor::process_getSiteConfiguration(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getSiteConfiguration", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getSiteConfiguration");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getSiteConfiguration");
  }

  AccumuloProxy_getSiteConfiguration_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getSiteConfiguration", bytes);
  }

  AccumuloProxy_getSiteConfiguration_result result;
  try {
    iface_->getSiteConfiguration(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getSiteConfiguration");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getSiteConfiguration", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getSiteConfiguration");
  }

  oprot->writeMessageBegin("getSiteConfiguration", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getSiteConfiguration", bytes);
  }
}

void AccumuloProxyProcessor::process_getSystemConfiguration(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getSystemConfiguration", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getSystemConfiguration");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getSystemConfiguration");
  }

  AccumuloProxy_getSystemConfiguration_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getSystemConfiguration", bytes);
  }

  AccumuloProxy_getSystemConfiguration_result result;
  try {
    iface_->getSystemConfiguration(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getSystemConfiguration");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getSystemConfiguration", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getSystemConfiguration");
  }

  oprot->writeMessageBegin("getSystemConfiguration", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getSystemConfiguration", bytes);
  }
}

void AccumuloProxyProcessor::process_getTabletServers(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getTabletServers", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getTabletServers");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getTabletServers");
  }

  AccumuloProxy_getTabletServers_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getTabletServers", bytes);
  }

  AccumuloProxy_getTabletServers_result result;
  try {
    iface_->getTabletServers(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getTabletServers");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getTabletServers", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getTabletServers");
  }

  oprot->writeMessageBegin("getTabletServers", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getTabletServers", bytes);
  }
}

void AccumuloProxyProcessor::process_removeProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeProperty", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeProperty");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeProperty");
  }

  AccumuloProxy_removeProperty_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeProperty", bytes);
  }

  AccumuloProxy_removeProperty_result result;
  try {
    iface_->removeProperty(args.sharedSecret, args.property);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeProperty");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeProperty");
  }

  oprot->writeMessageBegin("removeProperty", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeProperty", bytes);
  }
}

void AccumuloProxyProcessor::process_setProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.setProperty", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.setProperty");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.setProperty");
  }

  AccumuloProxy_setProperty_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.setProperty", bytes);
  }

  AccumuloProxy_setProperty_result result;
  try {
    iface_->setProperty(args.sharedSecret, args.property, args.value);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.setProperty");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("setProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.setProperty");
  }

  oprot->writeMessageBegin("setProperty", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.setProperty", bytes);
  }
}

void AccumuloProxyProcessor::process_testClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.testClassLoad", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.testClassLoad");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.testClassLoad");
  }

  AccumuloProxy_testClassLoad_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.testClassLoad", bytes);
  }

  AccumuloProxy_testClassLoad_result result;
  try {
    result.success = iface_->testClassLoad(args.sharedSecret, args.className, args.asTypeName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.testClassLoad");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("testClassLoad", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.testClassLoad");
  }

  oprot->writeMessageBegin("testClassLoad", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.testClassLoad", bytes);
  }
}

void AccumuloProxyProcessor::process_authenticateUser(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.authenticateUser", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.authenticateUser");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.authenticateUser");
  }

  AccumuloProxy_authenticateUser_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.authenticateUser", bytes);
  }

  AccumuloProxy_authenticateUser_result result;
  try {
    result.success = iface_->authenticateUser(args.sharedSecret, args.user, args.properties);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.authenticateUser");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("authenticateUser", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.authenticateUser");
  }

  oprot->writeMessageBegin("authenticateUser", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.authenticateUser", bytes);
  }
}

void AccumuloProxyProcessor::process_changeUserAuthorizations(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.changeUserAuthorizations", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.changeUserAuthorizations");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.changeUserAuthorizations");
  }

  AccumuloProxy_changeUserAuthorizations_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.changeUserAuthorizations", bytes);
  }

  AccumuloProxy_changeUserAuthorizations_result result;
  try {
    iface_->changeUserAuthorizations(args.sharedSecret, args.user, args.authorizations);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.changeUserAuthorizations");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("changeUserAuthorizations", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.changeUserAuthorizations");
  }

  oprot->writeMessageBegin("changeUserAuthorizations", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.changeUserAuthorizations", bytes);
  }
}

void AccumuloProxyProcessor::process_changeLocalUserPassword(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.changeLocalUserPassword", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.changeLocalUserPassword");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.changeLocalUserPassword");
  }

  AccumuloProxy_changeLocalUserPassword_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.changeLocalUserPassword", bytes);
  }

  AccumuloProxy_changeLocalUserPassword_result result;
  try {
    iface_->changeLocalUserPassword(args.sharedSecret, args.user, args.password);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.changeLocalUserPassword");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("changeLocalUserPassword", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.changeLocalUserPassword");
  }

  oprot->writeMessageBegin("changeLocalUserPassword", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.changeLocalUserPassword", bytes);
  }
}

void AccumuloProxyProcessor::process_createLocalUser(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createLocalUser", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createLocalUser");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createLocalUser");
  }

  AccumuloProxy_createLocalUser_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createLocalUser", bytes);
  }

  AccumuloProxy_createLocalUser_result result;
  try {
    iface_->createLocalUser(args.sharedSecret, args.user, args.password);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createLocalUser");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createLocalUser", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createLocalUser");
  }

  oprot->writeMessageBegin("createLocalUser", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createLocalUser", bytes);
  }
}

void AccumuloProxyProcessor::process_dropLocalUser(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.dropLocalUser", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.dropLocalUser");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.dropLocalUser");
  }

  AccumuloProxy_dropLocalUser_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.dropLocalUser", bytes);
  }

  AccumuloProxy_dropLocalUser_result result;
  try {
    iface_->dropLocalUser(args.sharedSecret, args.user);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.dropLocalUser");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("dropLocalUser", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.dropLocalUser");
  }

  oprot->writeMessageBegin("dropLocalUser", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.dropLocalUser", bytes);
  }
}

void AccumuloProxyProcessor::process_getUserAuthorizations(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getUserAuthorizations", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getUserAuthorizations");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getUserAuthorizations");
  }

  AccumuloProxy_getUserAuthorizations_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getUserAuthorizations", bytes);
  }

  AccumuloProxy_getUserAuthorizations_result result;
  try {
    iface_->getUserAuthorizations(result.success, args.sharedSecret, args.user);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getUserAuthorizations");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getUserAuthorizations", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getUserAuthorizations");
  }

  oprot->writeMessageBegin("getUserAuthorizations", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getUserAuthorizations", bytes);
  }
}

void AccumuloProxyProcessor::process_grantSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.grantSystemPermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.grantSystemPermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.grantSystemPermission");
  }

  AccumuloProxy_grantSystemPermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.grantSystemPermission", bytes);
  }

  AccumuloProxy_grantSystemPermission_result result;
  try {
    iface_->grantSystemPermission(args.sharedSecret, args.user, args.perm);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.grantSystemPermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("grantSystemPermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.grantSystemPermission");
  }

  oprot->writeMessageBegin("grantSystemPermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.grantSystemPermission", bytes);
  }
}

void AccumuloProxyProcessor::process_grantTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.grantTablePermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.grantTablePermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.grantTablePermission");
  }

  AccumuloProxy_grantTablePermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.grantTablePermission", bytes);
  }

  AccumuloProxy_grantTablePermission_result result;
  try {
    iface_->grantTablePermission(args.sharedSecret, args.user, args.table, args.perm);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.grantTablePermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("grantTablePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.grantTablePermission");
  }

  oprot->writeMessageBegin("grantTablePermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.grantTablePermission", bytes);
  }
}

void AccumuloProxyProcessor::process_hasSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.hasSystemPermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.hasSystemPermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.hasSystemPermission");
  }

  AccumuloProxy_hasSystemPermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.hasSystemPermission", bytes);
  }

  AccumuloProxy_hasSystemPermission_result result;
  try {
    result.success = iface_->hasSystemPermission(args.sharedSecret, args.user, args.perm);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.hasSystemPermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("hasSystemPermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.hasSystemPermission");
  }

  oprot->writeMessageBegin("hasSystemPermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.hasSystemPermission", bytes);
  }
}

void AccumuloProxyProcessor::process_hasTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.hasTablePermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.hasTablePermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.hasTablePermission");
  }

  AccumuloProxy_hasTablePermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.hasTablePermission", bytes);
  }

  AccumuloProxy_hasTablePermission_result result;
  try {
    result.success = iface_->hasTablePermission(args.sharedSecret, args.user, args.table, args.perm);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.hasTablePermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("hasTablePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.hasTablePermission");
  }

  oprot->writeMessageBegin("hasTablePermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.hasTablePermission", bytes);
  }
}

void AccumuloProxyProcessor::process_listLocalUsers(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listLocalUsers", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listLocalUsers");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listLocalUsers");
  }

  AccumuloProxy_listLocalUsers_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listLocalUsers", bytes);
  }

  AccumuloProxy_listLocalUsers_result result;
  try {
    iface_->listLocalUsers(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listLocalUsers");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listLocalUsers", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listLocalUsers");
  }

  oprot->writeMessageBegin("listLocalUsers", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listLocalUsers", bytes);
  }
}

void AccumuloProxyProcessor::process_revokeSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.revokeSystemPermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.revokeSystemPermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.revokeSystemPermission");
  }

  AccumuloProxy_revokeSystemPermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.revokeSystemPermission", bytes);
  }

  AccumuloProxy_revokeSystemPermission_result result;
  try {
    iface_->revokeSystemPermission(args.sharedSecret, args.user, args.perm);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.revokeSystemPermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("revokeSystemPermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.revokeSystemPermission");
  }

  oprot->writeMessageBegin("revokeSystemPermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.revokeSystemPermission", bytes);
  }
}

void AccumuloProxyProcessor::process_revokeTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.revokeTablePermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.revokeTablePermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.revokeTablePermission");
  }

  AccumuloProxy_revokeTablePermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.revokeTablePermission", bytes);
  }

  AccumuloProxy_revokeTablePermission_result result;
  try {
    iface_->revokeTablePermission(args.sharedSecret, args.user, args.table, args.perm);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.revokeTablePermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("revokeTablePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.revokeTablePermission");
  }

  oprot->writeMessageBegin("revokeTablePermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.revokeTablePermission", bytes);
  }
}

void AccumuloProxyProcessor::process_grantNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.grantNamespacePermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.grantNamespacePermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.grantNamespacePermission");
  }

  AccumuloProxy_grantNamespacePermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.grantNamespacePermission", bytes);
  }

  AccumuloProxy_grantNamespacePermission_result result;
  try {
    iface_->grantNamespacePermission(args.sharedSecret, args.user, args.namespaceName, args.perm);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.grantNamespacePermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.grantNamespacePermission");
  }

  oprot->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.grantNamespacePermission", bytes);
  }
}

void AccumuloProxyProcessor::process_hasNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.hasNamespacePermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.hasNamespacePermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.hasNamespacePermission");
  }

  AccumuloProxy_hasNamespacePermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.hasNamespacePermission", bytes);
  }

  AccumuloProxy_hasNamespacePermission_result result;
  try {
    result.success = iface_->hasNamespacePermission(args.sharedSecret, args.user, args.namespaceName, args.perm);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.hasNamespacePermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.hasNamespacePermission");
  }

  oprot->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.hasNamespacePermission", bytes);
  }
}

void AccumuloProxyProcessor::process_revokeNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.revokeNamespacePermission", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.revokeNamespacePermission");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.revokeNamespacePermission");
  }

  AccumuloProxy_revokeNamespacePermission_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.revokeNamespacePermission", bytes);
  }

  AccumuloProxy_revokeNamespacePermission_result result;
  try {
    iface_->revokeNamespacePermission(args.sharedSecret, args.user, args.namespaceName, args.perm);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.revokeNamespacePermission");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.revokeNamespacePermission");
  }

  oprot->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.revokeNamespacePermission", bytes);
  }
}

void AccumuloProxyProcessor::process_createBatchScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createBatchScanner", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createBatchScanner");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createBatchScanner");
  }

  AccumuloProxy_createBatchScanner_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createBatchScanner", bytes);
  }

  AccumuloProxy_createBatchScanner_result result;
  try {
    iface_->createBatchScanner(result.success, args.sharedSecret, args.tableName, args.options);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createBatchScanner");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createBatchScanner", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createBatchScanner");
  }

  oprot->writeMessageBegin("createBatchScanner", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createBatchScanner", bytes);
  }
}

void AccumuloProxyProcessor::process_createScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createScanner", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createScanner");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createScanner");
  }

  AccumuloProxy_createScanner_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createScanner", bytes);
  }

  AccumuloProxy_createScanner_result result;
  try {
    iface_->createScanner(result.success, args.sharedSecret, args.tableName, args.options);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createScanner");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createScanner", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createScanner");
  }

  oprot->writeMessageBegin("createScanner", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createScanner", bytes);
  }
}

void AccumuloProxyProcessor::process_hasNext(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.hasNext", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.hasNext");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.hasNext");
  }

  AccumuloProxy_hasNext_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.hasNext", bytes);
  }

  AccumuloProxy_hasNext_result result;
  try {
    result.success = iface_->hasNext(args.scanner);
    result.__isset.success = true;
  } catch (UnknownScanner &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.hasNext");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("hasNext", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.hasNext");
  }

  oprot->writeMessageBegin("hasNext", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.hasNext", bytes);
  }
}

void AccumuloProxyProcessor::process_nextEntry(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.nextEntry", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.nextEntry");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.nextEntry");
  }

  AccumuloProxy_nextEntry_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.nextEntry", bytes);
  }

  AccumuloProxy_nextEntry_result result;
  try {
    iface_->nextEntry(result.success, args.scanner);
    result.__isset.success = true;
  } catch (NoMoreEntriesException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (UnknownScanner &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (AccumuloSecurityException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.nextEntry");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("nextEntry", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.nextEntry");
  }

  oprot->writeMessageBegin("nextEntry", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.nextEntry", bytes);
  }
}

void AccumuloProxyProcessor::process_nextK(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.nextK", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.nextK");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.nextK");
  }

  AccumuloProxy_nextK_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.nextK", bytes);
  }

  AccumuloProxy_nextK_result result;
  try {
    iface_->nextK(result.success, args.scanner, args.k);
    result.__isset.success = true;
  } catch (NoMoreEntriesException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (UnknownScanner &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (AccumuloSecurityException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.nextK");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("nextK", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.nextK");
  }

  oprot->writeMessageBegin("nextK", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.nextK", bytes);
  }
}

void AccumuloProxyProcessor::process_closeScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.closeScanner", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.closeScanner");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.closeScanner");
  }

  AccumuloProxy_closeScanner_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.closeScanner", bytes);
  }

  AccumuloProxy_closeScanner_result result;
  try {
    iface_->closeScanner(args.scanner);
  } catch (UnknownScanner &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.closeScanner");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("closeScanner", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.closeScanner");
  }

  oprot->writeMessageBegin("closeScanner", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.closeScanner", bytes);
  }
}

void AccumuloProxyProcessor::process_updateAndFlush(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.updateAndFlush", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.updateAndFlush");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.updateAndFlush");
  }

  AccumuloProxy_updateAndFlush_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.updateAndFlush", bytes);
  }

  AccumuloProxy_updateAndFlush_result result;
  try {
    iface_->updateAndFlush(args.sharedSecret, args.tableName, args.cells);
  } catch (AccumuloException &outch1) {
    result.outch1 = std::move(outch1);
    result.__isset.outch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (MutationsRejectedException &ouch4) {
    result.ouch4 = std::move(ouch4);
    result.__isset.ouch4 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.updateAndFlush");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("updateAndFlush", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.updateAndFlush");
  }

  oprot->writeMessageBegin("updateAndFlush", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.updateAndFlush", bytes);
  }
}

void AccumuloProxyProcessor::process_createWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createWriter", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createWriter");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createWriter");
  }

  AccumuloProxy_createWriter_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createWriter", bytes);
  }

  AccumuloProxy_createWriter_result result;
  try {
    iface_->createWriter(result.success, args.sharedSecret, args.tableName, args.opts);
    result.__isset.success = true;
  } catch (AccumuloException &outch1) {
    result.outch1 = std::move(outch1);
    result.__isset.outch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createWriter");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createWriter", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createWriter");
  }

  oprot->writeMessageBegin("createWriter", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createWriter", bytes);
  }
}

void AccumuloProxyProcessor::process_update(int32_t, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol*, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.update", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.update");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.update");
  }

  AccumuloProxy_update_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.update", bytes);
  }

  try {
    iface_->update(args.writer, args.cells);
  } catch (const std::exception&) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.update");
    }
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->asyncComplete(ctx, "AccumuloProxy.update");
  }

  return;
}

void AccumuloProxyProcessor::process_flush(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.flush", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.flush");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.flush");
  }

  AccumuloProxy_flush_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.flush", bytes);
  }

  AccumuloProxy_flush_result result;
  try {
    iface_->flush(args.writer);
  } catch (UnknownWriter &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (MutationsRejectedException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.flush");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("flush", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.flush");
  }

  oprot->writeMessageBegin("flush", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.flush", bytes);
  }
}

void AccumuloProxyProcessor::process_closeWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.closeWriter", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.closeWriter");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.closeWriter");
  }

  AccumuloProxy_closeWriter_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.closeWriter", bytes);
  }

  AccumuloProxy_closeWriter_result result;
  try {
    iface_->closeWriter(args.writer);
  } catch (UnknownWriter &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (MutationsRejectedException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.closeWriter");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("closeWriter", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.closeWriter");
  }

  oprot->writeMessageBegin("closeWriter", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.closeWriter", bytes);
  }
}

void AccumuloProxyProcessor::process_updateRowConditionally(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.updateRowConditionally", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.updateRowConditionally");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.updateRowConditionally");
  }

  AccumuloProxy_updateRowConditionally_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.updateRowConditionally", bytes);
  }

  AccumuloProxy_updateRowConditionally_result result;
  try {
    result.success = iface_->updateRowConditionally(args.sharedSecret, args.tableName, args.row, args.updates);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.updateRowConditionally");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("updateRowConditionally", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.updateRowConditionally");
  }

  oprot->writeMessageBegin("updateRowConditionally", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.updateRowConditionally", bytes);
  }
}

void AccumuloProxyProcessor::process_createConditionalWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createConditionalWriter", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createConditionalWriter");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createConditionalWriter");
  }

  AccumuloProxy_createConditionalWriter_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createConditionalWriter", bytes);
  }

  AccumuloProxy_createConditionalWriter_result result;
  try {
    iface_->createConditionalWriter(result.success, args.sharedSecret, args.tableName, args.options);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (TableNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createConditionalWriter");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createConditionalWriter", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createConditionalWriter");
  }

  oprot->writeMessageBegin("createConditionalWriter", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createConditionalWriter", bytes);
  }
}

void AccumuloProxyProcessor::process_updateRowsConditionally(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.updateRowsConditionally", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.updateRowsConditionally");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.updateRowsConditionally");
  }

  AccumuloProxy_updateRowsConditionally_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.updateRowsConditionally", bytes);
  }

  AccumuloProxy_updateRowsConditionally_result result;
  try {
    iface_->updateRowsConditionally(result.success, args.conditionalWriter, args.updates);
    result.__isset.success = true;
  } catch (UnknownWriter &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (AccumuloSecurityException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.updateRowsConditionally");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("updateRowsConditionally", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.updateRowsConditionally");
  }

  oprot->writeMessageBegin("updateRowsConditionally", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.updateRowsConditionally", bytes);
  }
}

void AccumuloProxyProcessor::process_closeConditionalWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.closeConditionalWriter", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.closeConditionalWriter");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.closeConditionalWriter");
  }

  AccumuloProxy_closeConditionalWriter_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.closeConditionalWriter", bytes);
  }

  AccumuloProxy_closeConditionalWriter_result result;
  try {
    iface_->closeConditionalWriter(args.conditionalWriter);
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.closeConditionalWriter");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("closeConditionalWriter", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.closeConditionalWriter");
  }

  oprot->writeMessageBegin("closeConditionalWriter", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.closeConditionalWriter", bytes);
  }
}

void AccumuloProxyProcessor::process_getRowRange(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getRowRange", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getRowRange");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getRowRange");
  }

  AccumuloProxy_getRowRange_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getRowRange", bytes);
  }

  AccumuloProxy_getRowRange_result result;
  try {
    iface_->getRowRange(result.success, args.row);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getRowRange");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getRowRange", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getRowRange");
  }

  oprot->writeMessageBegin("getRowRange", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getRowRange", bytes);
  }
}

void AccumuloProxyProcessor::process_getFollowing(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getFollowing", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getFollowing");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getFollowing");
  }

  AccumuloProxy_getFollowing_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getFollowing", bytes);
  }

  AccumuloProxy_getFollowing_result result;
  try {
    iface_->getFollowing(result.success, args.key, args.part);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getFollowing");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getFollowing", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getFollowing");
  }

  oprot->writeMessageBegin("getFollowing", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getFollowing", bytes);
  }
}

void AccumuloProxyProcessor::process_systemNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.systemNamespace", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.systemNamespace");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.systemNamespace");
  }

  AccumuloProxy_systemNamespace_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.systemNamespace", bytes);
  }

  AccumuloProxy_systemNamespace_result result;
  try {
    iface_->systemNamespace(result.success);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.systemNamespace");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.systemNamespace");
  }

  oprot->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.systemNamespace", bytes);
  }
}

void AccumuloProxyProcessor::process_defaultNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.defaultNamespace", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.defaultNamespace");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.defaultNamespace");
  }

  AccumuloProxy_defaultNamespace_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.defaultNamespace", bytes);
  }

  AccumuloProxy_defaultNamespace_result result;
  try {
    iface_->defaultNamespace(result.success);
    result.__isset.success = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.defaultNamespace");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.defaultNamespace");
  }

  oprot->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.defaultNamespace", bytes);
  }
}

void AccumuloProxyProcessor::process_listNamespaces(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listNamespaces", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listNamespaces");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listNamespaces");
  }

  AccumuloProxy_listNamespaces_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listNamespaces", bytes);
  }

  AccumuloProxy_listNamespaces_result result;
  try {
    iface_->listNamespaces(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listNamespaces");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listNamespaces");
  }

  oprot->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listNamespaces", bytes);
  }
}

void AccumuloProxyProcessor::process_namespaceExists(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.namespaceExists", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.namespaceExists");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.namespaceExists");
  }

  AccumuloProxy_namespaceExists_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.namespaceExists", bytes);
  }

  AccumuloProxy_namespaceExists_result result;
  try {
    result.success = iface_->namespaceExists(args.sharedSecret, args.namespaceName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.namespaceExists");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.namespaceExists");
  }

  oprot->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.namespaceExists", bytes);
  }
}

void AccumuloProxyProcessor::process_createNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.createNamespace", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createNamespace");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.createNamespace");
  }

  AccumuloProxy_createNamespace_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.createNamespace", bytes);
  }

  AccumuloProxy_createNamespace_result result;
  try {
    iface_->createNamespace(args.sharedSecret, args.namespaceName);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceExistsException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createNamespace");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createNamespace");
  }

  oprot->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createNamespace", bytes);
  }
}

void AccumuloProxyProcessor::process_deleteNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.deleteNamespace", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.deleteNamespace");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.deleteNamespace");
  }

  AccumuloProxy_deleteNamespace_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.deleteNamespace", bytes);
  }

  AccumuloProxy_deleteNamespace_result result;
  try {
    iface_->deleteNamespace(args.sharedSecret, args.namespaceName);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (NamespaceNotEmptyException &ouch4) {
    result.ouch4 = std::move(ouch4);
    result.__isset.ouch4 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.deleteNamespace");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.deleteNamespace");
  }

  oprot->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.deleteNamespace", bytes);
  }
}

void AccumuloProxyProcessor::process_renameNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.renameNamespace", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.renameNamespace");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.renameNamespace");
  }

  AccumuloProxy_renameNamespace_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.renameNamespace", bytes);
  }

  AccumuloProxy_renameNamespace_result result;
  try {
    iface_->renameNamespace(args.sharedSecret, args.oldNamespaceName, args.newNamespaceName);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (NamespaceExistsException &ouch4) {
    result.ouch4 = std::move(ouch4);
    result.__isset.ouch4 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.renameNamespace");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.renameNamespace");
  }

  oprot->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.renameNamespace", bytes);
  }
}

void AccumuloProxyProcessor::process_setNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.setNamespaceProperty", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.setNamespaceProperty");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.setNamespaceProperty");
  }

  AccumuloProxy_setNamespaceProperty_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.setNamespaceProperty", bytes);
  }

  AccumuloProxy_setNamespaceProperty_result result;
  try {
    iface_->setNamespaceProperty(args.sharedSecret, args.namespaceName, args.property, args.value);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.setNamespaceProperty");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.setNamespaceProperty");
  }

  oprot->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.setNamespaceProperty", bytes);
  }
}

void AccumuloProxyProcessor::process_removeNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeNamespaceProperty", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeNamespaceProperty");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeNamespaceProperty");
  }

  AccumuloProxy_removeNamespaceProperty_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeNamespaceProperty", bytes);
  }

  AccumuloProxy_removeNamespaceProperty_result result;
  try {
    iface_->removeNamespaceProperty(args.sharedSecret, args.namespaceName, args.property);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeNamespaceProperty");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeNamespaceProperty");
  }

  oprot->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeNamespaceProperty", bytes);
  }
}

void AccumuloProxyProcessor::process_getNamespaceProperties(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getNamespaceProperties", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getNamespaceProperties");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getNamespaceProperties");
  }

  AccumuloProxy_getNamespaceProperties_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getNamespaceProperties", bytes);
  }

  AccumuloProxy_getNamespaceProperties_result result;
  try {
    iface_->getNamespaceProperties(result.success, args.sharedSecret, args.namespaceName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getNamespaceProperties");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getNamespaceProperties");
  }

  oprot->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getNamespaceProperties", bytes);
  }
}

void AccumuloProxyProcessor::process_namespaceIdMap(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.namespaceIdMap", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.namespaceIdMap");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.namespaceIdMap");
  }

  AccumuloProxy_namespaceIdMap_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.namespaceIdMap", bytes);
  }

  AccumuloProxy_namespaceIdMap_result result;
  try {
    iface_->namespaceIdMap(result.success, args.sharedSecret);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.namespaceIdMap");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.namespaceIdMap");
  }

  oprot->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.namespaceIdMap", bytes);
  }
}

void AccumuloProxyProcessor::process_attachNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.attachNamespaceIterator", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.attachNamespaceIterator");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.attachNamespaceIterator");
  }

  AccumuloProxy_attachNamespaceIterator_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.attachNamespaceIterator", bytes);
  }

  AccumuloProxy_attachNamespaceIterator_result result;
  try {
    iface_->attachNamespaceIterator(args.sharedSecret, args.namespaceName, args.setting, args.scopes);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.attachNamespaceIterator");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.attachNamespaceIterator");
  }

  oprot->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.attachNamespaceIterator", bytes);
  }
}

void AccumuloProxyProcessor::process_removeNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeNamespaceIterator", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeNamespaceIterator");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeNamespaceIterator");
  }

  AccumuloProxy_removeNamespaceIterator_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeNamespaceIterator", bytes);
  }

  AccumuloProxy_removeNamespaceIterator_result result;
  try {
    iface_->removeNamespaceIterator(args.sharedSecret, args.namespaceName, args.name, args.scopes);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeNamespaceIterator");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeNamespaceIterator");
  }

  oprot->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeNamespaceIterator", bytes);
  }
}

void AccumuloProxyProcessor::process_getNamespaceIteratorSetting(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.getNamespaceIteratorSetting", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getNamespaceIteratorSetting");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.getNamespaceIteratorSetting");
  }

  AccumuloProxy_getNamespaceIteratorSetting_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.getNamespaceIteratorSetting", bytes);
  }

  AccumuloProxy_getNamespaceIteratorSetting_result result;
  try {
    iface_->getNamespaceIteratorSetting(result.success, args.sharedSecret, args.namespaceName, args.name, args.scope);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getNamespaceIteratorSetting");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getNamespaceIteratorSetting");
  }

  oprot->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getNamespaceIteratorSetting", bytes);
  }
}

void AccumuloProxyProcessor::process_listNamespaceIterators(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listNamespaceIterators", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listNamespaceIterators");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listNamespaceIterators");
  }

  AccumuloProxy_listNamespaceIterators_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listNamespaceIterators", bytes);
  }

  AccumuloProxy_listNamespaceIterators_result result;
  try {
    iface_->listNamespaceIterators(result.success, args.sharedSecret, args.namespaceName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listNamespaceIterators");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listNamespaceIterators");
  }

  oprot->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listNamespaceIterators", bytes);
  }
}

void AccumuloProxyProcessor::process_checkNamespaceIteratorConflicts(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.checkNamespaceIteratorConflicts", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
  }

  AccumuloProxy_checkNamespaceIteratorConflicts_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts", bytes);
  }

  AccumuloProxy_checkNamespaceIteratorConflicts_result result;
  try {
    iface_->checkNamespaceIteratorConflicts(args.sharedSecret, args.namespaceName, args.setting, args.scopes);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
  }

  oprot->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts", bytes);
  }
}

void AccumuloProxyProcessor::process_addNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.addNamespaceConstraint", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.addNamespaceConstraint");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.addNamespaceConstraint");
  }

  AccumuloProxy_addNamespaceConstraint_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.addNamespaceConstraint", bytes);
  }

  AccumuloProxy_addNamespaceConstraint_result result;
  try {
    result.success = iface_->addNamespaceConstraint(args.sharedSecret, args.namespaceName, args.constraintClassName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.addNamespaceConstraint");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.addNamespaceConstraint");
  }

  oprot->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.addNamespaceConstraint", bytes);
  }
}

void AccumuloProxyProcessor::process_removeNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.removeNamespaceConstraint", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeNamespaceConstraint");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeNamespaceConstraint");
  }

  AccumuloProxy_removeNamespaceConstraint_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeNamespaceConstraint", bytes);
  }

  AccumuloProxy_removeNamespaceConstraint_result result;
  try {
    iface_->removeNamespaceConstraint(args.sharedSecret, args.namespaceName, args.id);
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeNamespaceConstraint");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeNamespaceConstraint");
  }

  oprot->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeNamespaceConstraint", bytes);
  }
}

void AccumuloProxyProcessor::process_listNamespaceConstraints(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.listNamespaceConstraints", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listNamespaceConstraints");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.listNamespaceConstraints");
  }

  AccumuloProxy_listNamespaceConstraints_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.listNamespaceConstraints", bytes);
  }

  AccumuloProxy_listNamespaceConstraints_result result;
  try {
    iface_->listNamespaceConstraints(result.success, args.sharedSecret, args.namespaceName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listNamespaceConstraints");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listNamespaceConstraints");
  }

  oprot->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listNamespaceConstraints", bytes);
  }
}

void AccumuloProxyProcessor::process_testNamespaceClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
{
  void* ctx = nullptr;
  if (this->eventHandler_.get() != nullptr) {
    ctx = this->eventHandler_->getContext("AccumuloProxy.testNamespaceClassLoad", callContext);
  }
  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.testNamespaceClassLoad");

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preRead(ctx, "AccumuloProxy.testNamespaceClassLoad");
  }

  AccumuloProxy_testNamespaceClassLoad_args args;
  args.read(iprot);
  iprot->readMessageEnd();
  uint32_t bytes = iprot->getTransport()->readEnd();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postRead(ctx, "AccumuloProxy.testNamespaceClassLoad", bytes);
  }

  AccumuloProxy_testNamespaceClassLoad_result result;
  try {
    result.success = iface_->testNamespaceClassLoad(args.sharedSecret, args.namespaceName, args.className, args.asTypeName);
    result.__isset.success = true;
  } catch (AccumuloException &ouch1) {
    result.ouch1 = std::move(ouch1);
    result.__isset.ouch1 = true;
  } catch (AccumuloSecurityException &ouch2) {
    result.ouch2 = std::move(ouch2);
    result.__isset.ouch2 = true;
  } catch (NamespaceNotFoundException &ouch3) {
    result.ouch3 = std::move(ouch3);
    result.__isset.ouch3 = true;
  } catch (const std::exception& e) {
    if (this->eventHandler_.get() != nullptr) {
      this->eventHandler_->handlerError(ctx, "AccumuloProxy.testNamespaceClassLoad");
    }

    ::apache::thrift::TApplicationException x(e.what());
    oprot->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_EXCEPTION, seqid);
    x.write(oprot);
    oprot->writeMessageEnd();
    oprot->getTransport()->writeEnd();
    oprot->getTransport()->flush();
    return;
  }

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->preWrite(ctx, "AccumuloProxy.testNamespaceClassLoad");
  }

  oprot->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_REPLY, seqid);
  result.write(oprot);
  oprot->writeMessageEnd();
  bytes = oprot->getTransport()->writeEnd();
  oprot->getTransport()->flush();

  if (this->eventHandler_.get() != nullptr) {
    this->eventHandler_->postWrite(ctx, "AccumuloProxy.testNamespaceClassLoad", bytes);
  }
}

::std::shared_ptr< ::apache::thrift::TProcessor > AccumuloProxyProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
  ::apache::thrift::ReleaseHandler< AccumuloProxyIfFactory > cleanup(handlerFactory_);
  ::std::shared_ptr< AccumuloProxyIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
  ::std::shared_ptr< ::apache::thrift::TProcessor > processor(new AccumuloProxyProcessor(handler));
  return processor;
}

int32_t AccumuloProxyConcurrentClient::addConstraint(const std::string& sharedSecret, const std::string& tableName, const std::string& constraintClassName)
{
  int32_t seqid = send_addConstraint(sharedSecret, tableName, constraintClassName);
  return recv_addConstraint(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_addConstraint(const std::string& sharedSecret, const std::string& tableName, const std::string& constraintClassName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("addConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_addConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.constraintClassName = &constraintClassName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

int32_t AccumuloProxyConcurrentClient::recv_addConstraint(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("addConstraint") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      int32_t _return;
      AccumuloProxy_addConstraint_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addConstraint failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::addSplits(const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & splits)
{
  int32_t seqid = send_addSplits(sharedSecret, tableName, splits);
  recv_addSplits(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_addSplits(const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & splits)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("addSplits", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_addSplits_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.splits = &splits;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_addSplits(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("addSplits") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_addSplits_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::attachIterator(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t seqid = send_attachIterator(sharedSecret, tableName, setting, scopes);
  recv_attachIterator(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_attachIterator(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("attachIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_attachIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_attachIterator(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("attachIterator") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_attachIterator_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::checkIteratorConflicts(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t seqid = send_checkIteratorConflicts(sharedSecret, tableName, setting, scopes);
  recv_checkIteratorConflicts(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_checkIteratorConflicts(const std::string& sharedSecret, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("checkIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_checkIteratorConflicts_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_checkIteratorConflicts(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("checkIteratorConflicts") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_checkIteratorConflicts_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::clearLocatorCache(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_clearLocatorCache(sharedSecret, tableName);
  recv_clearLocatorCache(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_clearLocatorCache(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("clearLocatorCache", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_clearLocatorCache_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_clearLocatorCache(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("clearLocatorCache") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_clearLocatorCache_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::cloneTable(const std::string& sharedSecret, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude)
{
  int32_t seqid = send_cloneTable(sharedSecret, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
  recv_cloneTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_cloneTable(const std::string& sharedSecret, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("cloneTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_cloneTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.newTableName = &newTableName;
  args.flush = &flush;
  args.propertiesToSet = &propertiesToSet;
  args.propertiesToExclude = &propertiesToExclude;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_cloneTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("cloneTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_cloneTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      if (result.__isset.ouch4) {
        sentry.commit();
        throw result.ouch4;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::compactTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const PluginConfig& selectorConfig, const PluginConfig& configurerConfig)
{
  int32_t seqid = send_compactTable(sharedSecret, tableName, startRow, endRow, iterators, flush, wait, selectorConfig, configurerConfig);
  recv_compactTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_compactTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const PluginConfig& selectorConfig, const PluginConfig& configurerConfig)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("compactTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_compactTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.iterators = &iterators;
  args.flush = &flush;
  args.wait = &wait;
  args.selectorConfig = &selectorConfig;
  args.configurerConfig = &configurerConfig;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_compactTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("compactTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_compactTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::cancelCompaction(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_cancelCompaction(sharedSecret, tableName);
  recv_cancelCompaction(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_cancelCompaction(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("cancelCompaction", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_cancelCompaction_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_cancelCompaction(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("cancelCompaction") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_cancelCompaction_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createTable(const std::string& sharedSecret, const std::string& tableName, const bool versioningIter, const TimeType::type type)
{
  int32_t seqid = send_createTable(sharedSecret, tableName, versioningIter, type);
  recv_createTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createTable(const std::string& sharedSecret, const std::string& tableName, const bool versioningIter, const TimeType::type type)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.versioningIter = &versioningIter;
  args.type = &type;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::deleteTable(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_deleteTable(sharedSecret, tableName);
  recv_deleteTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_deleteTable(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("deleteTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_deleteTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_deleteTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("deleteTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_deleteTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::deleteRows(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  int32_t seqid = send_deleteRows(sharedSecret, tableName, startRow, endRow);
  recv_deleteRows(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_deleteRows(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("deleteRows", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_deleteRows_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_deleteRows(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("deleteRows") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_deleteRows_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::exportTable(const std::string& sharedSecret, const std::string& tableName, const std::string& exportDir)
{
  int32_t seqid = send_exportTable(sharedSecret, tableName, exportDir);
  recv_exportTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_exportTable(const std::string& sharedSecret, const std::string& tableName, const std::string& exportDir)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("exportTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_exportTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.exportDir = &exportDir;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_exportTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("exportTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_exportTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::flushTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait)
{
  int32_t seqid = send_flushTable(sharedSecret, tableName, startRow, endRow, wait);
  recv_flushTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_flushTable(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("flushTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_flushTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.wait = &wait;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_flushTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("flushTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_flushTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getDiskUsage(std::vector<DiskUsage> & _return, const std::string& sharedSecret, const std::set<std::string> & tables)
{
  int32_t seqid = send_getDiskUsage(sharedSecret, tables);
  recv_getDiskUsage(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getDiskUsage(const std::string& sharedSecret, const std::set<std::string> & tables)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getDiskUsage", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getDiskUsage_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tables = &tables;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getDiskUsage(std::vector<DiskUsage> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getDiskUsage") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getDiskUsage_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getDiskUsage failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_getLocalityGroups(sharedSecret, tableName);
  recv_getLocalityGroups(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getLocalityGroups(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getLocalityGroups", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getLocalityGroups_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getLocalityGroups") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getLocalityGroups_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getLocalityGroups failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getIteratorSetting(IteratorSetting& _return, const std::string& sharedSecret, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope)
{
  int32_t seqid = send_getIteratorSetting(sharedSecret, tableName, iteratorName, scope);
  recv_getIteratorSetting(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getIteratorSetting(const std::string& sharedSecret, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getIteratorSetting_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.iteratorName = &iteratorName;
  args.scope = &scope;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getIteratorSetting(IteratorSetting& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getIteratorSetting") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getIteratorSetting_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getIteratorSetting failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getMaxRow(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive)
{
  int32_t seqid = send_getMaxRow(sharedSecret, tableName, auths, startRow, startInclusive, endRow, endInclusive);
  recv_getMaxRow(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getMaxRow(const std::string& sharedSecret, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getMaxRow", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getMaxRow_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.auths = &auths;
  args.startRow = &startRow;
  args.startInclusive = &startInclusive;
  args.endRow = &endRow;
  args.endInclusive = &endInclusive;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getMaxRow(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getMaxRow") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getMaxRow_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getMaxRow failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getTableProperties(std::map<std::string, std::string> & _return, const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_getTableProperties(sharedSecret, tableName);
  recv_getTableProperties(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getTableProperties(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getTableProperties", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getTableProperties_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getTableProperties(std::map<std::string, std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getTableProperties") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getTableProperties_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getTableProperties failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::importDirectory(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime)
{
  int32_t seqid = send_importDirectory(sharedSecret, tableName, importDir, failureDir, setTime);
  recv_importDirectory(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_importDirectory(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("importDirectory", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_importDirectory_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.importDir = &importDir;
  args.failureDir = &failureDir;
  args.setTime = &setTime;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_importDirectory(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("importDirectory") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_importDirectory_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      if (result.__isset.ouch4) {
        sentry.commit();
        throw result.ouch4;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::importTable(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir)
{
  int32_t seqid = send_importTable(sharedSecret, tableName, importDir);
  recv_importTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_importTable(const std::string& sharedSecret, const std::string& tableName, const std::string& importDir)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("importTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_importTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.importDir = &importDir;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_importTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("importTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_importTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listSplits(std::vector<std::string> & _return, const std::string& sharedSecret, const std::string& tableName, const int32_t maxSplits)
{
  int32_t seqid = send_listSplits(sharedSecret, tableName, maxSplits);
  recv_listSplits(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listSplits(const std::string& sharedSecret, const std::string& tableName, const int32_t maxSplits)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listSplits", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listSplits_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.maxSplits = &maxSplits;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listSplits(std::vector<std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listSplits") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listSplits_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listSplits failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listTables(std::set<std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_listTables(sharedSecret);
  recv_listTables(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listTables(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listTables", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listTables_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listTables(std::set<std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listTables") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listTables_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listTables failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_listIterators(sharedSecret, tableName);
  recv_listIterators(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listIterators(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listIterators", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listIterators_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listIterators") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listIterators_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listIterators failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listConstraints(std::map<std::string, int32_t> & _return, const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_listConstraints(sharedSecret, tableName);
  recv_listConstraints(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listConstraints(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listConstraints", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listConstraints_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listConstraints") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listConstraints_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listConstraints failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::mergeTablets(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  int32_t seqid = send_mergeTablets(sharedSecret, tableName, startRow, endRow);
  recv_mergeTablets(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_mergeTablets(const std::string& sharedSecret, const std::string& tableName, const std::string& startRow, const std::string& endRow)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("mergeTablets", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_mergeTablets_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.startRow = &startRow;
  args.endRow = &endRow;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_mergeTablets(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("mergeTablets") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_mergeTablets_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::offlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  int32_t seqid = send_offlineTable(sharedSecret, tableName, wait);
  recv_offlineTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_offlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("offlineTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_offlineTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.wait = &wait;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_offlineTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("offlineTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_offlineTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::onlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  int32_t seqid = send_onlineTable(sharedSecret, tableName, wait);
  recv_onlineTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_onlineTable(const std::string& sharedSecret, const std::string& tableName, const bool wait)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("onlineTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_onlineTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.wait = &wait;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_onlineTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("onlineTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_onlineTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeConstraint(const std::string& sharedSecret, const std::string& tableName, const int32_t constraint)
{
  int32_t seqid = send_removeConstraint(sharedSecret, tableName, constraint);
  recv_removeConstraint(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeConstraint(const std::string& sharedSecret, const std::string& tableName, const int32_t constraint)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.constraint = &constraint;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeConstraint(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeConstraint") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeConstraint_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeIterator(const std::string& sharedSecret, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes)
{
  int32_t seqid = send_removeIterator(sharedSecret, tableName, iterName, scopes);
  recv_removeIterator(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeIterator(const std::string& sharedSecret, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.iterName = &iterName;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeIterator(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeIterator") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeIterator_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property)
{
  int32_t seqid = send_removeTableProperty(sharedSecret, tableName, property);
  recv_removeTableProperty(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeTableProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeTableProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.property = &property;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeTableProperty(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeTableProperty") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeTableProperty_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::renameTable(const std::string& sharedSecret, const std::string& oldTableName, const std::string& newTableName)
{
  int32_t seqid = send_renameTable(sharedSecret, oldTableName, newTableName);
  recv_renameTable(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_renameTable(const std::string& sharedSecret, const std::string& oldTableName, const std::string& newTableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("renameTable", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_renameTable_pargs args;
  args.sharedSecret = &sharedSecret;
  args.oldTableName = &oldTableName;
  args.newTableName = &newTableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_renameTable(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("renameTable") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_renameTable_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      if (result.__isset.ouch4) {
        sentry.commit();
        throw result.ouch4;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::setLocalityGroups(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups)
{
  int32_t seqid = send_setLocalityGroups(sharedSecret, tableName, groups);
  recv_setLocalityGroups(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_setLocalityGroups(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("setLocalityGroups", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setLocalityGroups_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.groups = &groups;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_setLocalityGroups(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("setLocalityGroups") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_setLocalityGroups_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::setTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property, const std::string& value)
{
  int32_t seqid = send_setTableProperty(sharedSecret, tableName, property, value);
  recv_setTableProperty(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_setTableProperty(const std::string& sharedSecret, const std::string& tableName, const std::string& property, const std::string& value)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("setTableProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setTableProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.property = &property;
  args.value = &value;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_setTableProperty(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("setTableProperty") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_setTableProperty_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::splitRangeByTablets(std::set<Range> & _return, const std::string& sharedSecret, const std::string& tableName, const Range& range, const int32_t maxSplits)
{
  int32_t seqid = send_splitRangeByTablets(sharedSecret, tableName, range, maxSplits);
  recv_splitRangeByTablets(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_splitRangeByTablets(const std::string& sharedSecret, const std::string& tableName, const Range& range, const int32_t maxSplits)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("splitRangeByTablets", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_splitRangeByTablets_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.range = &range;
  args.maxSplits = &maxSplits;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_splitRangeByTablets(std::set<Range> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("splitRangeByTablets") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_splitRangeByTablets_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "splitRangeByTablets failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::tableExists(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t seqid = send_tableExists(sharedSecret, tableName);
  return recv_tableExists(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_tableExists(const std::string& sharedSecret, const std::string& tableName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("tableExists", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_tableExists_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_tableExists(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("tableExists") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_tableExists_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "tableExists failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::tableIdMap(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_tableIdMap(sharedSecret);
  recv_tableIdMap(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_tableIdMap(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("tableIdMap", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_tableIdMap_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_tableIdMap(std::map<std::string, std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("tableIdMap") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_tableIdMap_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "tableIdMap failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::testTableClassLoad(const std::string& sharedSecret, const std::string& tableName, const std::string& className, const std::string& asTypeName)
{
  int32_t seqid = send_testTableClassLoad(sharedSecret, tableName, className, asTypeName);
  return recv_testTableClassLoad(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_testTableClassLoad(const std::string& sharedSecret, const std::string& tableName, const std::string& className, const std::string& asTypeName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("testTableClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_testTableClassLoad_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.className = &className;
  args.asTypeName = &asTypeName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_testTableClassLoad(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("testTableClassLoad") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_testTableClassLoad_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testTableClassLoad failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::pingTabletServer(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t seqid = send_pingTabletServer(sharedSecret, tserver);
  recv_pingTabletServer(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_pingTabletServer(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("pingTabletServer", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_pingTabletServer_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tserver = &tserver;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_pingTabletServer(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("pingTabletServer") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_pingTabletServer_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getActiveScans(std::vector<ActiveScan> & _return, const std::string& sharedSecret, const std::string& tserver)
{
  int32_t seqid = send_getActiveScans(sharedSecret, tserver);
  recv_getActiveScans(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getActiveScans(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getActiveScans", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getActiveScans_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tserver = &tserver;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getActiveScans(std::vector<ActiveScan> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getActiveScans") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getActiveScans_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getActiveScans failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& sharedSecret, const std::string& tserver)
{
  int32_t seqid = send_getActiveCompactions(sharedSecret, tserver);
  recv_getActiveCompactions(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getActiveCompactions(const std::string& sharedSecret, const std::string& tserver)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getActiveCompactions", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getActiveCompactions_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tserver = &tserver;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getActiveCompactions(std::vector<ActiveCompaction> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getActiveCompactions") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getActiveCompactions_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getActiveCompactions failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_getSiteConfiguration(sharedSecret);
  recv_getSiteConfiguration(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getSiteConfiguration(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getSiteConfiguration", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getSiteConfiguration_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getSiteConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getSiteConfiguration") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getSiteConfiguration_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSiteConfiguration failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_getSystemConfiguration(sharedSecret);
  recv_getSystemConfiguration(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getSystemConfiguration(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getSystemConfiguration", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getSystemConfiguration_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getSystemConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getSystemConfiguration") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getSystemConfiguration_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSystemConfiguration failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getTabletServers(std::vector<std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_getTabletServers(sharedSecret);
  recv_getTabletServers(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getTabletServers(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getTabletServers", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getTabletServers_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getTabletServers(std::vector<std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getTabletServers") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getTabletServers_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getTabletServers failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeProperty(const std::string& sharedSecret, const std::string& property)
{
  int32_t seqid = send_removeProperty(sharedSecret, property);
  recv_removeProperty(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeProperty(const std::string& sharedSecret, const std::string& property)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.property = &property;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeProperty(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeProperty") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeProperty_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::setProperty(const std::string& sharedSecret, const std::string& property, const std::string& value)
{
  int32_t seqid = send_setProperty(sharedSecret, property, value);
  recv_setProperty(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_setProperty(const std::string& sharedSecret, const std::string& property, const std::string& value)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("setProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.property = &property;
  args.value = &value;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_setProperty(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("setProperty") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_setProperty_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::testClassLoad(const std::string& sharedSecret, const std::string& className, const std::string& asTypeName)
{
  int32_t seqid = send_testClassLoad(sharedSecret, className, asTypeName);
  return recv_testClassLoad(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_testClassLoad(const std::string& sharedSecret, const std::string& className, const std::string& asTypeName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("testClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_testClassLoad_pargs args;
  args.sharedSecret = &sharedSecret;
  args.className = &className;
  args.asTypeName = &asTypeName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_testClassLoad(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("testClassLoad") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_testClassLoad_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testClassLoad failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::authenticateUser(const std::string& sharedSecret, const std::string& user, const std::map<std::string, std::string> & properties)
{
  int32_t seqid = send_authenticateUser(sharedSecret, user, properties);
  return recv_authenticateUser(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_authenticateUser(const std::string& sharedSecret, const std::string& user, const std::map<std::string, std::string> & properties)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("authenticateUser", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_authenticateUser_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.properties = &properties;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_authenticateUser(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("authenticateUser") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_authenticateUser_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "authenticateUser failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::changeUserAuthorizations(const std::string& sharedSecret, const std::string& user, const std::set<std::string> & authorizations)
{
  int32_t seqid = send_changeUserAuthorizations(sharedSecret, user, authorizations);
  recv_changeUserAuthorizations(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_changeUserAuthorizations(const std::string& sharedSecret, const std::string& user, const std::set<std::string> & authorizations)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("changeUserAuthorizations", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_changeUserAuthorizations_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.authorizations = &authorizations;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_changeUserAuthorizations(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("changeUserAuthorizations") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_changeUserAuthorizations_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::changeLocalUserPassword(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  int32_t seqid = send_changeLocalUserPassword(sharedSecret, user, password);
  recv_changeLocalUserPassword(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_changeLocalUserPassword(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("changeLocalUserPassword", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_changeLocalUserPassword_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.password = &password;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_changeLocalUserPassword(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("changeLocalUserPassword") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_changeLocalUserPassword_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createLocalUser(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  int32_t seqid = send_createLocalUser(sharedSecret, user, password);
  recv_createLocalUser(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createLocalUser(const std::string& sharedSecret, const std::string& user, const std::string& password)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createLocalUser", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createLocalUser_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.password = &password;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createLocalUser(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createLocalUser") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createLocalUser_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::dropLocalUser(const std::string& sharedSecret, const std::string& user)
{
  int32_t seqid = send_dropLocalUser(sharedSecret, user);
  recv_dropLocalUser(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_dropLocalUser(const std::string& sharedSecret, const std::string& user)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("dropLocalUser", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_dropLocalUser_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_dropLocalUser(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("dropLocalUser") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_dropLocalUser_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getUserAuthorizations(std::vector<std::string> & _return, const std::string& sharedSecret, const std::string& user)
{
  int32_t seqid = send_getUserAuthorizations(sharedSecret, user);
  recv_getUserAuthorizations(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getUserAuthorizations(const std::string& sharedSecret, const std::string& user)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getUserAuthorizations", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getUserAuthorizations_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getUserAuthorizations(std::vector<std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getUserAuthorizations") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getUserAuthorizations_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getUserAuthorizations failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::grantSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t seqid = send_grantSystemPermission(sharedSecret, user, perm);
  recv_grantSystemPermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_grantSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("grantSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_grantSystemPermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_grantSystemPermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("grantSystemPermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_grantSystemPermission_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::grantTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t seqid = send_grantTablePermission(sharedSecret, user, table, perm);
  recv_grantTablePermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_grantTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("grantTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_grantTablePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.table = &table;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_grantTablePermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("grantTablePermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_grantTablePermission_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::hasSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t seqid = send_hasSystemPermission(sharedSecret, user, perm);
  return recv_hasSystemPermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_hasSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("hasSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasSystemPermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_hasSystemPermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("hasSystemPermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_hasSystemPermission_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasSystemPermission failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::hasTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t seqid = send_hasTablePermission(sharedSecret, user, table, perm);
  return recv_hasTablePermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_hasTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("hasTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasTablePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.table = &table;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_hasTablePermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("hasTablePermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_hasTablePermission_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasTablePermission failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listLocalUsers(std::set<std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_listLocalUsers(sharedSecret);
  recv_listLocalUsers(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listLocalUsers(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listLocalUsers", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listLocalUsers_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listLocalUsers(std::set<std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listLocalUsers") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listLocalUsers_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listLocalUsers failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::revokeSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t seqid = send_revokeSystemPermission(sharedSecret, user, perm);
  recv_revokeSystemPermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_revokeSystemPermission(const std::string& sharedSecret, const std::string& user, const SystemPermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("revokeSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_revokeSystemPermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_revokeSystemPermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("revokeSystemPermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_revokeSystemPermission_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::revokeTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t seqid = send_revokeTablePermission(sharedSecret, user, table, perm);
  recv_revokeTablePermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_revokeTablePermission(const std::string& sharedSecret, const std::string& user, const std::string& table, const TablePermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("revokeTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_revokeTablePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.table = &table;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_revokeTablePermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("revokeTablePermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_revokeTablePermission_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::grantNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t seqid = send_grantNamespacePermission(sharedSecret, user, namespaceName, perm);
  recv_grantNamespacePermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_grantNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_grantNamespacePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.namespaceName = &namespaceName;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_grantNamespacePermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("grantNamespacePermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_grantNamespacePermission_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::hasNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t seqid = send_hasNamespacePermission(sharedSecret, user, namespaceName, perm);
  return recv_hasNamespacePermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_hasNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasNamespacePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.namespaceName = &namespaceName;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_hasNamespacePermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("hasNamespacePermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_hasNamespacePermission_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNamespacePermission failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::revokeNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t seqid = send_revokeNamespacePermission(sharedSecret, user, namespaceName, perm);
  recv_revokeNamespacePermission(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_revokeNamespacePermission(const std::string& sharedSecret, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_revokeNamespacePermission_pargs args;
  args.sharedSecret = &sharedSecret;
  args.user = &user;
  args.namespaceName = &namespaceName;
  args.perm = &perm;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_revokeNamespacePermission(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("revokeNamespacePermission") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_revokeNamespacePermission_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createBatchScanner(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const BatchScanOptions& options)
{
  int32_t seqid = send_createBatchScanner(sharedSecret, tableName, options);
  recv_createBatchScanner(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createBatchScanner(const std::string& sharedSecret, const std::string& tableName, const BatchScanOptions& options)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createBatchScanner", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createBatchScanner_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.options = &options;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createBatchScanner(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createBatchScanner") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createBatchScanner_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createBatchScanner failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createScanner(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const ScanOptions& options)
{
  int32_t seqid = send_createScanner(sharedSecret, tableName, options);
  recv_createScanner(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createScanner(const std::string& sharedSecret, const std::string& tableName, const ScanOptions& options)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createScanner", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createScanner_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.options = &options;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createScanner(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createScanner") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createScanner_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createScanner failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::hasNext(const std::string& scanner)
{
  int32_t seqid = send_hasNext(scanner);
  return recv_hasNext(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_hasNext(const std::string& scanner)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("hasNext", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_hasNext_pargs args;
  args.scanner = &scanner;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_hasNext(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("hasNext") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_hasNext_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNext failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::nextEntry(KeyValueAndPeek& _return, const std::string& scanner)
{
  int32_t seqid = send_nextEntry(scanner);
  recv_nextEntry(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_nextEntry(const std::string& scanner)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("nextEntry", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_nextEntry_pargs args;
  args.scanner = &scanner;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_nextEntry(KeyValueAndPeek& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("nextEntry") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_nextEntry_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "nextEntry failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::nextK(ScanResult& _return, const std::string& scanner, const int32_t k)
{
  int32_t seqid = send_nextK(scanner, k);
  recv_nextK(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_nextK(const std::string& scanner, const int32_t k)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("nextK", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_nextK_pargs args;
  args.scanner = &scanner;
  args.k = &k;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_nextK(ScanResult& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("nextK") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_nextK_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "nextK failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::closeScanner(const std::string& scanner)
{
  int32_t seqid = send_closeScanner(scanner);
  recv_closeScanner(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_closeScanner(const std::string& scanner)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("closeScanner", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_closeScanner_pargs args;
  args.scanner = &scanner;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_closeScanner(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("closeScanner") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_closeScanner_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::updateAndFlush(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  int32_t seqid = send_updateAndFlush(sharedSecret, tableName, cells);
  recv_updateAndFlush(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_updateAndFlush(const std::string& sharedSecret, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("updateAndFlush", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_updateAndFlush_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.cells = &cells;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_updateAndFlush(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("updateAndFlush") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_updateAndFlush_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.outch1) {
        sentry.commit();
        throw result.outch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      if (result.__isset.ouch4) {
        sentry.commit();
        throw result.ouch4;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createWriter(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const WriterOptions& opts)
{
  int32_t seqid = send_createWriter(sharedSecret, tableName, opts);
  recv_createWriter(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createWriter(const std::string& sharedSecret, const std::string& tableName, const WriterOptions& opts)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createWriter_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.opts = &opts;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createWriter(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createWriter") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createWriter_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.outch1) {
        sentry.commit();
        throw result.outch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createWriter failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  send_update(writer, cells);
}

void AccumuloProxyConcurrentClient::send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
{
  int32_t cseqid = 0;
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("update", ::apache::thrift::protocol::T_ONEWAY, cseqid);

  AccumuloProxy_update_pargs args;
  args.writer = &writer;
  args.cells = &cells;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
}

void AccumuloProxyConcurrentClient::flush(const std::string& writer)
{
  int32_t seqid = send_flush(writer);
  recv_flush(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_flush(const std::string& writer)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("flush", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_flush_pargs args;
  args.writer = &writer;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_flush(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("flush") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_flush_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::closeWriter(const std::string& writer)
{
  int32_t seqid = send_closeWriter(writer);
  recv_closeWriter(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_closeWriter(const std::string& writer)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("closeWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_closeWriter_pargs args;
  args.writer = &writer;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_closeWriter(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("closeWriter") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_closeWriter_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

ConditionalStatus::type AccumuloProxyConcurrentClient::updateRowConditionally(const std::string& sharedSecret, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates)
{
  int32_t seqid = send_updateRowConditionally(sharedSecret, tableName, row, updates);
  return recv_updateRowConditionally(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_updateRowConditionally(const std::string& sharedSecret, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("updateRowConditionally", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_updateRowConditionally_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.row = &row;
  args.updates = &updates;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

ConditionalStatus::type AccumuloProxyConcurrentClient::recv_updateRowConditionally(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("updateRowConditionally") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      ConditionalStatus::type _return;
      AccumuloProxy_updateRowConditionally_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "updateRowConditionally failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createConditionalWriter(std::string& _return, const std::string& sharedSecret, const std::string& tableName, const ConditionalWriterOptions& options)
{
  int32_t seqid = send_createConditionalWriter(sharedSecret, tableName, options);
  recv_createConditionalWriter(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createConditionalWriter(const std::string& sharedSecret, const std::string& tableName, const ConditionalWriterOptions& options)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createConditionalWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createConditionalWriter_pargs args;
  args.sharedSecret = &sharedSecret;
  args.tableName = &tableName;
  args.options = &options;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createConditionalWriter(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createConditionalWriter") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createConditionalWriter_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createConditionalWriter failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates)
{
  int32_t seqid = send_updateRowsConditionally(conditionalWriter, updates);
  recv_updateRowsConditionally(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_updateRowsConditionally(const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("updateRowsConditionally", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_updateRowsConditionally_pargs args;
  args.conditionalWriter = &conditionalWriter;
  args.updates = &updates;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("updateRowsConditionally") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_updateRowsConditionally_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "updateRowsConditionally failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::closeConditionalWriter(const std::string& conditionalWriter)
{
  int32_t seqid = send_closeConditionalWriter(conditionalWriter);
  recv_closeConditionalWriter(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_closeConditionalWriter(const std::string& conditionalWriter)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("closeConditionalWriter", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_closeConditionalWriter_pargs args;
  args.conditionalWriter = &conditionalWriter;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_closeConditionalWriter(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("closeConditionalWriter") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_closeConditionalWriter_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getRowRange(Range& _return, const std::string& row)
{
  int32_t seqid = send_getRowRange(row);
  recv_getRowRange(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getRowRange(const std::string& row)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getRowRange", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getRowRange_pargs args;
  args.row = &row;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getRowRange(Range& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getRowRange") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getRowRange_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getRowRange failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getFollowing(Key& _return, const Key& key, const PartialKey::type part)
{
  int32_t seqid = send_getFollowing(key, part);
  recv_getFollowing(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getFollowing(const Key& key, const PartialKey::type part)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getFollowing", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getFollowing_pargs args;
  args.key = &key;
  args.part = &part;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getFollowing(Key& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getFollowing") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getFollowing_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getFollowing failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::systemNamespace(std::string& _return)
{
  int32_t seqid = send_systemNamespace();
  recv_systemNamespace(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_systemNamespace()
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_systemNamespace_pargs args;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_systemNamespace(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("systemNamespace") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_systemNamespace_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "systemNamespace failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::defaultNamespace(std::string& _return)
{
  int32_t seqid = send_defaultNamespace();
  recv_defaultNamespace(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_defaultNamespace()
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_defaultNamespace_pargs args;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_defaultNamespace(std::string& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("defaultNamespace") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_defaultNamespace_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "defaultNamespace failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listNamespaces(std::vector<std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_listNamespaces(sharedSecret);
  recv_listNamespaces(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listNamespaces(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listNamespaces_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listNamespaces(std::vector<std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listNamespaces") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listNamespaces_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaces failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::namespaceExists(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t seqid = send_namespaceExists(sharedSecret, namespaceName);
  return recv_namespaceExists(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_namespaceExists(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_namespaceExists_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_namespaceExists(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("namespaceExists") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_namespaceExists_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceExists failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::createNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t seqid = send_createNamespace(sharedSecret, namespaceName);
  recv_createNamespace(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_createNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_createNamespace_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_createNamespace(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("createNamespace") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_createNamespace_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::deleteNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t seqid = send_deleteNamespace(sharedSecret, namespaceName);
  recv_deleteNamespace(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_deleteNamespace(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_deleteNamespace_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_deleteNamespace(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("deleteNamespace") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_deleteNamespace_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      if (result.__isset.ouch4) {
        sentry.commit();
        throw result.ouch4;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::renameNamespace(const std::string& sharedSecret, const std::string& oldNamespaceName, const std::string& newNamespaceName)
{
  int32_t seqid = send_renameNamespace(sharedSecret, oldNamespaceName, newNamespaceName);
  recv_renameNamespace(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_renameNamespace(const std::string& sharedSecret, const std::string& oldNamespaceName, const std::string& newNamespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_renameNamespace_pargs args;
  args.sharedSecret = &sharedSecret;
  args.oldNamespaceName = &oldNamespaceName;
  args.newNamespaceName = &newNamespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_renameNamespace(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("renameNamespace") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_renameNamespace_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      if (result.__isset.ouch4) {
        sentry.commit();
        throw result.ouch4;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::setNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property, const std::string& value)
{
  int32_t seqid = send_setNamespaceProperty(sharedSecret, namespaceName, property, value);
  recv_setNamespaceProperty(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_setNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property, const std::string& value)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_setNamespaceProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.property = &property;
  args.value = &value;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_setNamespaceProperty(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("setNamespaceProperty") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_setNamespaceProperty_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property)
{
  int32_t seqid = send_removeNamespaceProperty(sharedSecret, namespaceName, property);
  recv_removeNamespaceProperty(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeNamespaceProperty(const std::string& sharedSecret, const std::string& namespaceName, const std::string& property)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeNamespaceProperty_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.property = &property;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeNamespaceProperty(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeNamespaceProperty") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeNamespaceProperty_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t seqid = send_getNamespaceProperties(sharedSecret, namespaceName);
  recv_getNamespaceProperties(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getNamespaceProperties(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getNamespaceProperties_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getNamespaceProperties(std::map<std::string, std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getNamespaceProperties") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getNamespaceProperties_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceProperties failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& sharedSecret)
{
  int32_t seqid = send_namespaceIdMap(sharedSecret);
  recv_namespaceIdMap(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_namespaceIdMap(const std::string& sharedSecret)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_namespaceIdMap_pargs args;
  args.sharedSecret = &sharedSecret;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_namespaceIdMap(std::map<std::string, std::string> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("namespaceIdMap") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_namespaceIdMap_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceIdMap failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::attachNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t seqid = send_attachNamespaceIterator(sharedSecret, namespaceName, setting, scopes);
  recv_attachNamespaceIterator(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_attachNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_attachNamespaceIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_attachNamespaceIterator(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("attachNamespaceIterator") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_attachNamespaceIterator_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
{
  int32_t seqid = send_removeNamespaceIterator(sharedSecret, namespaceName, name, scopes);
  recv_removeNamespaceIterator(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeNamespaceIterator(const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeNamespaceIterator_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.name = &name;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeNamespaceIterator(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeNamespaceIterator") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeNamespaceIterator_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
{
  int32_t seqid = send_getNamespaceIteratorSetting(sharedSecret, namespaceName, name, scope);
  recv_getNamespaceIteratorSetting(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_getNamespaceIteratorSetting(const std::string& sharedSecret, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_getNamespaceIteratorSetting_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.name = &name;
  args.scope = &scope;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_getNamespaceIteratorSetting(IteratorSetting& _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("getNamespaceIteratorSetting") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_getNamespaceIteratorSetting_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t seqid = send_listNamespaceIterators(sharedSecret, namespaceName);
  recv_listNamespaceIterators(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listNamespaceIterators(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listNamespaceIterators_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listNamespaceIterators") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listNamespaceIterators_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceIterators failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::checkNamespaceIteratorConflicts(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t seqid = send_checkNamespaceIteratorConflicts(sharedSecret, namespaceName, setting, scopes);
  recv_checkNamespaceIteratorConflicts(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_checkNamespaceIteratorConflicts(const std::string& sharedSecret, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_checkNamespaceIteratorConflicts_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.setting = &setting;
  args.scopes = &scopes;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_checkNamespaceIteratorConflicts(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("checkNamespaceIteratorConflicts") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_checkNamespaceIteratorConflicts_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

int32_t AccumuloProxyConcurrentClient::addNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const std::string& constraintClassName)
{
  int32_t seqid = send_addNamespaceConstraint(sharedSecret, namespaceName, constraintClassName);
  return recv_addNamespaceConstraint(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_addNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const std::string& constraintClassName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_addNamespaceConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.constraintClassName = &constraintClassName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

int32_t AccumuloProxyConcurrentClient::recv_addNamespaceConstraint(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("addNamespaceConstraint") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      int32_t _return;
      AccumuloProxy_addNamespaceConstraint_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addNamespaceConstraint failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::removeNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const int32_t id)
{
  int32_t seqid = send_removeNamespaceConstraint(sharedSecret, namespaceName, id);
  recv_removeNamespaceConstraint(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_removeNamespaceConstraint(const std::string& sharedSecret, const std::string& namespaceName, const int32_t id)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_removeNamespaceConstraint_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.id = &id;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_removeNamespaceConstraint(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("removeNamespaceConstraint") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_removeNamespaceConstraint_presult result;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      sentry.commit();
      return;
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

void AccumuloProxyConcurrentClient::listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t seqid = send_listNamespaceConstraints(sharedSecret, namespaceName);
  recv_listNamespaceConstraints(_return, seqid);
}

int32_t AccumuloProxyConcurrentClient::send_listNamespaceConstraints(const std::string& sharedSecret, const std::string& namespaceName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_listNamespaceConstraints_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

void AccumuloProxyConcurrentClient::recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("listNamespaceConstraints") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      AccumuloProxy_listNamespaceConstraints_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        // _return pointer has now been filled
        sentry.commit();
        return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceConstraints failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

bool AccumuloProxyConcurrentClient::testNamespaceClassLoad(const std::string& sharedSecret, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
{
  int32_t seqid = send_testNamespaceClassLoad(sharedSecret, namespaceName, className, asTypeName);
  return recv_testNamespaceClassLoad(seqid);
}

int32_t AccumuloProxyConcurrentClient::send_testNamespaceClassLoad(const std::string& sharedSecret, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
{
  int32_t cseqid = this->sync_->generateSeqId();
  ::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());
  oprot_->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);

  AccumuloProxy_testNamespaceClassLoad_pargs args;
  args.sharedSecret = &sharedSecret;
  args.namespaceName = &namespaceName;
  args.className = &className;
  args.asTypeName = &asTypeName;
  args.write(oprot_);

  oprot_->writeMessageEnd();
  oprot_->getTransport()->writeEnd();
  oprot_->getTransport()->flush();

  sentry.commit();
  return cseqid;
}

bool AccumuloProxyConcurrentClient::recv_testNamespaceClassLoad(const int32_t seqid)
{

  int32_t rseqid = 0;
  std::string fname;
  ::apache::thrift::protocol::TMessageType mtype;

  // the read mutex gets dropped and reacquired as part of waitForWork()
  // The destructor of this sentry wakes up other clients
  ::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);

  while(true) {
    if(!this->sync_->getPending(fname, mtype, rseqid)) {
      iprot_->readMessageBegin(fname, mtype, rseqid);
    }
    if(seqid == rseqid) {
      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
        ::apache::thrift::TApplicationException x;
        x.read(iprot_);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
        sentry.commit();
        throw x;
      }
      if (mtype != ::apache::thrift::protocol::T_REPLY) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();
      }
      if (fname.compare("testNamespaceClassLoad") != 0) {
        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
        iprot_->readMessageEnd();
        iprot_->getTransport()->readEnd();

        // in a bad state, don't commit
        using ::apache::thrift::protocol::TProtocolException;
        throw TProtocolException(TProtocolException::INVALID_DATA);
      }
      bool _return;
      AccumuloProxy_testNamespaceClassLoad_presult result;
      result.success = &_return;
      result.read(iprot_);
      iprot_->readMessageEnd();
      iprot_->getTransport()->readEnd();

      if (result.__isset.success) {
        sentry.commit();
        return _return;
      }
      if (result.__isset.ouch1) {
        sentry.commit();
        throw result.ouch1;
      }
      if (result.__isset.ouch2) {
        sentry.commit();
        throw result.ouch2;
      }
      if (result.__isset.ouch3) {
        sentry.commit();
        throw result.ouch3;
      }
      // in a bad state, don't commit
      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testNamespaceClassLoad failed: unknown result");
    }
    // seqid != rseqid
    this->sync_->updatePending(fname, mtype, rseqid);

    // this will temporarily unlock the readMutex, and let other clients get work done
    this->sync_->waitForWork(seqid);
  } // end while(true)
}

} // namespace

