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

/**
 * Autogenerated by Thrift Compiler (0.10.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.appcatalog.accountprovisioning;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class SSHAccountProvisioner implements org.apache.thrift.TBase<SSHAccountProvisioner, SSHAccountProvisioner._Fields>, java.io.Serializable, Cloneable, Comparable<SSHAccountProvisioner> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SSHAccountProvisioner");

  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField CAN_CREATE_ACCOUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("canCreateAccount", org.apache.thrift.protocol.TType.BOOL, (short)2);
  private static final org.apache.thrift.protocol.TField CAN_INSTALL_SSHKEY_FIELD_DESC = new org.apache.thrift.protocol.TField("canInstallSSHKey", org.apache.thrift.protocol.TType.BOOL, (short)3);
  private static final org.apache.thrift.protocol.TField CONFIG_PARAMS_FIELD_DESC = new org.apache.thrift.protocol.TField("configParams", org.apache.thrift.protocol.TType.LIST, (short)4);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new SSHAccountProvisionerStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new SSHAccountProvisionerTupleSchemeFactory();

  private java.lang.String name; // required
  private boolean canCreateAccount; // required
  private boolean canInstallSSHKey; // required
  private java.util.List<SSHAccountProvisionerConfigParam> configParams; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    NAME((short)1, "name"),
    CAN_CREATE_ACCOUNT((short)2, "canCreateAccount"),
    CAN_INSTALL_SSHKEY((short)3, "canInstallSSHKey"),
    CONFIG_PARAMS((short)4, "configParams");

    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

    static {
      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // NAME
          return NAME;
        case 2: // CAN_CREATE_ACCOUNT
          return CAN_CREATE_ACCOUNT;
        case 3: // CAN_INSTALL_SSHKEY
          return CAN_INSTALL_SSHKEY;
        case 4: // CONFIG_PARAMS
          return CONFIG_PARAMS;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

    _Fields(short thriftId, java.lang.String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __CANCREATEACCOUNT_ISSET_ID = 0;
  private static final int __CANINSTALLSSHKEY_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.CAN_CREATE_ACCOUNT, new org.apache.thrift.meta_data.FieldMetaData("canCreateAccount", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.CAN_INSTALL_SSHKEY, new org.apache.thrift.meta_data.FieldMetaData("canInstallSSHKey", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.CONFIG_PARAMS, new org.apache.thrift.meta_data.FieldMetaData("configParams", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SSHAccountProvisionerConfigParam.class))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SSHAccountProvisioner.class, metaDataMap);
  }

  public SSHAccountProvisioner() {
  }

  public SSHAccountProvisioner(
    java.lang.String name,
    boolean canCreateAccount,
    boolean canInstallSSHKey,
    java.util.List<SSHAccountProvisionerConfigParam> configParams)
  {
    this();
    this.name = name;
    this.canCreateAccount = canCreateAccount;
    setCanCreateAccountIsSet(true);
    this.canInstallSSHKey = canInstallSSHKey;
    setCanInstallSSHKeyIsSet(true);
    this.configParams = configParams;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public SSHAccountProvisioner(SSHAccountProvisioner other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetName()) {
      this.name = other.name;
    }
    this.canCreateAccount = other.canCreateAccount;
    this.canInstallSSHKey = other.canInstallSSHKey;
    if (other.isSetConfigParams()) {
      java.util.List<SSHAccountProvisionerConfigParam> __this__configParams = new java.util.ArrayList<SSHAccountProvisionerConfigParam>(other.configParams.size());
      for (SSHAccountProvisionerConfigParam other_element : other.configParams) {
        __this__configParams.add(new SSHAccountProvisionerConfigParam(other_element));
      }
      this.configParams = __this__configParams;
    }
  }

  public SSHAccountProvisioner deepCopy() {
    return new SSHAccountProvisioner(this);
  }

  @Override
  public void clear() {
    this.name = null;
    setCanCreateAccountIsSet(false);
    this.canCreateAccount = false;
    setCanInstallSSHKeyIsSet(false);
    this.canInstallSSHKey = false;
    this.configParams = null;
  }

  public java.lang.String getName() {
    return this.name;
  }

  public void setName(java.lang.String name) {
    this.name = name;
  }

  public void unsetName() {
    this.name = null;
  }

  /** Returns true if field name is set (has been assigned a value) and false otherwise */
  public boolean isSetName() {
    return this.name != null;
  }

  public void setNameIsSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  public boolean isCanCreateAccount() {
    return this.canCreateAccount;
  }

  public void setCanCreateAccount(boolean canCreateAccount) {
    this.canCreateAccount = canCreateAccount;
    setCanCreateAccountIsSet(true);
  }

  public void unsetCanCreateAccount() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CANCREATEACCOUNT_ISSET_ID);
  }

  /** Returns true if field canCreateAccount is set (has been assigned a value) and false otherwise */
  public boolean isSetCanCreateAccount() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CANCREATEACCOUNT_ISSET_ID);
  }

  public void setCanCreateAccountIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CANCREATEACCOUNT_ISSET_ID, value);
  }

  public boolean isCanInstallSSHKey() {
    return this.canInstallSSHKey;
  }

  public void setCanInstallSSHKey(boolean canInstallSSHKey) {
    this.canInstallSSHKey = canInstallSSHKey;
    setCanInstallSSHKeyIsSet(true);
  }

  public void unsetCanInstallSSHKey() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CANINSTALLSSHKEY_ISSET_ID);
  }

  /** Returns true if field canInstallSSHKey is set (has been assigned a value) and false otherwise */
  public boolean isSetCanInstallSSHKey() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CANINSTALLSSHKEY_ISSET_ID);
  }

  public void setCanInstallSSHKeyIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CANINSTALLSSHKEY_ISSET_ID, value);
  }

  public int getConfigParamsSize() {
    return (this.configParams == null) ? 0 : this.configParams.size();
  }

  public java.util.Iterator<SSHAccountProvisionerConfigParam> getConfigParamsIterator() {
    return (this.configParams == null) ? null : this.configParams.iterator();
  }

  public void addToConfigParams(SSHAccountProvisionerConfigParam elem) {
    if (this.configParams == null) {
      this.configParams = new java.util.ArrayList<SSHAccountProvisionerConfigParam>();
    }
    this.configParams.add(elem);
  }

  public java.util.List<SSHAccountProvisionerConfigParam> getConfigParams() {
    return this.configParams;
  }

  public void setConfigParams(java.util.List<SSHAccountProvisionerConfigParam> configParams) {
    this.configParams = configParams;
  }

  public void unsetConfigParams() {
    this.configParams = null;
  }

  /** Returns true if field configParams is set (has been assigned a value) and false otherwise */
  public boolean isSetConfigParams() {
    return this.configParams != null;
  }

  public void setConfigParamsIsSet(boolean value) {
    if (!value) {
      this.configParams = null;
    }
  }

  public void setFieldValue(_Fields field, java.lang.Object value) {
    switch (field) {
    case NAME:
      if (value == null) {
        unsetName();
      } else {
        setName((java.lang.String)value);
      }
      break;

    case CAN_CREATE_ACCOUNT:
      if (value == null) {
        unsetCanCreateAccount();
      } else {
        setCanCreateAccount((java.lang.Boolean)value);
      }
      break;

    case CAN_INSTALL_SSHKEY:
      if (value == null) {
        unsetCanInstallSSHKey();
      } else {
        setCanInstallSSHKey((java.lang.Boolean)value);
      }
      break;

    case CONFIG_PARAMS:
      if (value == null) {
        unsetConfigParams();
      } else {
        setConfigParams((java.util.List<SSHAccountProvisionerConfigParam>)value);
      }
      break;

    }
  }

  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case NAME:
      return getName();

    case CAN_CREATE_ACCOUNT:
      return isCanCreateAccount();

    case CAN_INSTALL_SSHKEY:
      return isCanInstallSSHKey();

    case CONFIG_PARAMS:
      return getConfigParams();

    }
    throw new java.lang.IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new java.lang.IllegalArgumentException();
    }

    switch (field) {
    case NAME:
      return isSetName();
    case CAN_CREATE_ACCOUNT:
      return isSetCanCreateAccount();
    case CAN_INSTALL_SSHKEY:
      return isSetCanInstallSSHKey();
    case CONFIG_PARAMS:
      return isSetConfigParams();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.Object that) {
    if (that == null)
      return false;
    if (that instanceof SSHAccountProvisioner)
      return this.equals((SSHAccountProvisioner)that);
    return false;
  }

  public boolean equals(SSHAccountProvisioner that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_name = true && this.isSetName();
    boolean that_present_name = true && that.isSetName();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_canCreateAccount = true;
    boolean that_present_canCreateAccount = true;
    if (this_present_canCreateAccount || that_present_canCreateAccount) {
      if (!(this_present_canCreateAccount && that_present_canCreateAccount))
        return false;
      if (this.canCreateAccount != that.canCreateAccount)
        return false;
    }

    boolean this_present_canInstallSSHKey = true;
    boolean that_present_canInstallSSHKey = true;
    if (this_present_canInstallSSHKey || that_present_canInstallSSHKey) {
      if (!(this_present_canInstallSSHKey && that_present_canInstallSSHKey))
        return false;
      if (this.canInstallSSHKey != that.canInstallSSHKey)
        return false;
    }

    boolean this_present_configParams = true && this.isSetConfigParams();
    boolean that_present_configParams = true && that.isSetConfigParams();
    if (this_present_configParams || that_present_configParams) {
      if (!(this_present_configParams && that_present_configParams))
        return false;
      if (!this.configParams.equals(that.configParams))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
    if (isSetName())
      hashCode = hashCode * 8191 + name.hashCode();

    hashCode = hashCode * 8191 + ((canCreateAccount) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((canInstallSSHKey) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetConfigParams()) ? 131071 : 524287);
    if (isSetConfigParams())
      hashCode = hashCode * 8191 + configParams.hashCode();

    return hashCode;
  }

  @Override
  public int compareTo(SSHAccountProvisioner other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCanCreateAccount()).compareTo(other.isSetCanCreateAccount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCanCreateAccount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.canCreateAccount, other.canCreateAccount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetCanInstallSSHKey()).compareTo(other.isSetCanInstallSSHKey());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCanInstallSSHKey()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.canInstallSSHKey, other.canInstallSSHKey);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetConfigParams()).compareTo(other.isSetConfigParams());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetConfigParams()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.configParams, other.configParams);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("SSHAccountProvisioner(");
    boolean first = true;

    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("canCreateAccount:");
    sb.append(this.canCreateAccount);
    first = false;
    if (!first) sb.append(", ");
    sb.append("canInstallSSHKey:");
    sb.append(this.canInstallSSHKey);
    first = false;
    if (!first) sb.append(", ");
    sb.append("configParams:");
    if (this.configParams == null) {
      sb.append("null");
    } else {
      sb.append(this.configParams);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (!isSetName()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'name' is unset! Struct:" + toString());
    }

    if (!isSetCanCreateAccount()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'canCreateAccount' is unset! Struct:" + toString());
    }

    if (!isSetCanInstallSSHKey()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'canInstallSSHKey' is unset! Struct:" + toString());
    }

    if (!isSetConfigParams()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'configParams' is unset! Struct:" + toString());
    }

    // check for sub-struct validity
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class SSHAccountProvisionerStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public SSHAccountProvisionerStandardScheme getScheme() {
      return new SSHAccountProvisionerStandardScheme();
    }
  }

  private static class SSHAccountProvisionerStandardScheme extends org.apache.thrift.scheme.StandardScheme<SSHAccountProvisioner> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, SSHAccountProvisioner struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.setNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // CAN_CREATE_ACCOUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.canCreateAccount = iprot.readBool();
              struct.setCanCreateAccountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // CAN_INSTALL_SSHKEY
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.canInstallSSHKey = iprot.readBool();
              struct.setCanInstallSSHKeyIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // CONFIG_PARAMS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.configParams = new java.util.ArrayList<SSHAccountProvisionerConfigParam>(_list0.size);
                SSHAccountProvisionerConfigParam _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = new SSHAccountProvisionerConfigParam();
                  _elem1.read(iprot);
                  struct.configParams.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setConfigParamsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, SSHAccountProvisioner struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(CAN_CREATE_ACCOUNT_FIELD_DESC);
      oprot.writeBool(struct.canCreateAccount);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(CAN_INSTALL_SSHKEY_FIELD_DESC);
      oprot.writeBool(struct.canInstallSSHKey);
      oprot.writeFieldEnd();
      if (struct.configParams != null) {
        oprot.writeFieldBegin(CONFIG_PARAMS_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.configParams.size()));
          for (SSHAccountProvisionerConfigParam _iter3 : struct.configParams)
          {
            _iter3.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class SSHAccountProvisionerTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public SSHAccountProvisionerTupleScheme getScheme() {
      return new SSHAccountProvisionerTupleScheme();
    }
  }

  private static class SSHAccountProvisionerTupleScheme extends org.apache.thrift.scheme.TupleScheme<SSHAccountProvisioner> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, SSHAccountProvisioner struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.name);
      oprot.writeBool(struct.canCreateAccount);
      oprot.writeBool(struct.canInstallSSHKey);
      {
        oprot.writeI32(struct.configParams.size());
        for (SSHAccountProvisionerConfigParam _iter4 : struct.configParams)
        {
          _iter4.write(oprot);
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, SSHAccountProvisioner struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.name = iprot.readString();
      struct.setNameIsSet(true);
      struct.canCreateAccount = iprot.readBool();
      struct.setCanCreateAccountIsSet(true);
      struct.canInstallSSHKey = iprot.readBool();
      struct.setCanInstallSSHKeyIsSet(true);
      {
        org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.configParams = new java.util.ArrayList<SSHAccountProvisionerConfigParam>(_list5.size);
        SSHAccountProvisionerConfigParam _elem6;
        for (int _i7 = 0; _i7 < _list5.size; ++_i7)
        {
          _elem6 = new SSHAccountProvisionerConfigParam();
          _elem6.read(iprot);
          struct.configParams.add(_elem6);
        }
      }
      struct.setConfigParamsIsSet(true);
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

