/**
 * 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.allocation.manager.service.cpi;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class AllocationRegistryService {

  public interface Iface {

    /**
     * <p>API method to create new allocation requests</p>
     * 
     * @param allocDetail
     */
    public java.lang.String createAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) throws org.apache.thrift.TException;

    /**
     * <p>API method to check if the allocation request exists</p>
     * 
     * @param projectId
     * @param userName
     */
    public boolean isAllocationRequestExists(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to delete allocation request</p>
     * 
     * @param projectId
     * @param userName
     */
    public boolean deleteAllocationRequest(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to get an allocation Request</p>
     * 
     * @param projectId
     * @param userName
     */
    public org.apache.airavata.allocation.manager.models.UserAllocationDetail getAllocationRequest(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to update an allocation Request</p>
     * 
     * @param allocDetail
     */
    public boolean updateAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) throws org.apache.thrift.TException;

    /**
     * <p>API method to get an allocation Request status</p>
     * 
     * @param projectId
     * @param userName
     */
    public java.lang.String getAllocationRequestStatus(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to get an allocation Request PI email</p>
     * 
     * @param userName
     */
    public java.lang.String getAllocationRequestUserEmail(java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to get an allocation Request Admin email</p>
     * 
     * @param userType
     */
    public java.lang.String getAllocationManagerAdminEmail(java.lang.String userType) throws org.apache.thrift.TException;

    /**
     * <p>API method to get an allocation Request PI</p>
     * 
     * @param projectId
     */
    public java.lang.String getAllocationRequestUserName(java.lang.String projectId) throws org.apache.thrift.TException;

    /**
     * <p>API method to update the status of a request</p>
     * 
     * @param projectId
     * @param status
     */
    public void updateAllocationRequestStatus(java.lang.String projectId, java.lang.String status) throws org.apache.thrift.TException;

    /**
     * <p>API method to get all requests for admin</p>
     * 
     * @param userName
     */
    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getAllRequestsForAdmin(java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to assign reviewers</p>
     * 
     * @param projectId
     * @param userName
     */
    public boolean assignReviewers(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to update request submitted by reviewer</p>
     * 
     * @param projectId
     * @param userAllocationDetail
     */
    public boolean updateRequestByReviewer(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail) throws org.apache.thrift.TException;

    /**
     * <p>API method to check if the logged in user is an Admin</p>
     * 
     * @param userName
     */
    public boolean isAdmin(java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to check if the logged in user is a Reviewer</p>
     * 
     * @param userName
     */
    public boolean isReviewer(java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to get all requests assigned to the reviewers</p>
     * 
     * @param userName
     */
    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getAllRequestsForReviewers(java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to get a user details</p>
     * 
     * @param userName
     */
    public org.apache.airavata.allocation.manager.models.UserDetail getUserDetails(java.lang.String userName) throws org.apache.thrift.TException;

    /**
     * <p>API method to get all the reviews for a request</p>
     * 
     * @param projectId
     */
    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getReviewsForRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId) throws org.apache.thrift.TException;

  }

  public interface AsyncIface {

    public void createAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void isAllocationRequestExists(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deleteAllocationRequest(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getAllocationRequest(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserAllocationDetail> resultHandler) throws org.apache.thrift.TException;

    public void updateAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getAllocationRequestStatus(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void getAllocationRequestUserEmail(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void getAllocationManagerAdminEmail(java.lang.String userType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void getAllocationRequestUserName(java.lang.String projectId, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updateAllocationRequestStatus(java.lang.String projectId, java.lang.String status, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;

    public void getAllRequestsForAdmin(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException;

    public void assignReviewers(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void updateRequestByReviewer(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isAdmin(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isReviewer(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getAllRequestsForReviewers(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException;

    public void getUserDetails(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserDetail> resultHandler) throws org.apache.thrift.TException;

    public void getReviewsForRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException;

  }

  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
      public Factory() {}
      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
        return new Client(prot);
      }
      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

    public Client(org.apache.thrift.protocol.TProtocol prot)
    {
      super(prot, prot);
    }

    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
      super(iprot, oprot);
    }

    public java.lang.String createAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) throws org.apache.thrift.TException
    {
      send_createAllocationRequest(allocDetail);
      return recv_createAllocationRequest();
    }

    public void send_createAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) throws org.apache.thrift.TException
    {
      createAllocationRequest_args args = new createAllocationRequest_args();
      args.setAllocDetail(allocDetail);
      sendBase("createAllocationRequest", args);
    }

    public java.lang.String recv_createAllocationRequest() throws org.apache.thrift.TException
    {
      createAllocationRequest_result result = new createAllocationRequest_result();
      receiveBase(result, "createAllocationRequest");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createAllocationRequest failed: unknown result");
    }

    public boolean isAllocationRequestExists(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      send_isAllocationRequestExists(projectId, userName);
      return recv_isAllocationRequestExists();
    }

    public void send_isAllocationRequestExists(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      isAllocationRequestExists_args args = new isAllocationRequestExists_args();
      args.setProjectId(projectId);
      args.setUserName(userName);
      sendBase("isAllocationRequestExists", args);
    }

    public boolean recv_isAllocationRequestExists() throws org.apache.thrift.TException
    {
      isAllocationRequestExists_result result = new isAllocationRequestExists_result();
      receiveBase(result, "isAllocationRequestExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isAllocationRequestExists failed: unknown result");
    }

    public boolean deleteAllocationRequest(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      send_deleteAllocationRequest(projectId, userName);
      return recv_deleteAllocationRequest();
    }

    public void send_deleteAllocationRequest(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      deleteAllocationRequest_args args = new deleteAllocationRequest_args();
      args.setProjectId(projectId);
      args.setUserName(userName);
      sendBase("deleteAllocationRequest", args);
    }

    public boolean recv_deleteAllocationRequest() throws org.apache.thrift.TException
    {
      deleteAllocationRequest_result result = new deleteAllocationRequest_result();
      receiveBase(result, "deleteAllocationRequest");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteAllocationRequest failed: unknown result");
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail getAllocationRequest(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      send_getAllocationRequest(projectId, userName);
      return recv_getAllocationRequest();
    }

    public void send_getAllocationRequest(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      getAllocationRequest_args args = new getAllocationRequest_args();
      args.setProjectId(projectId);
      args.setUserName(userName);
      sendBase("getAllocationRequest", args);
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail recv_getAllocationRequest() throws org.apache.thrift.TException
    {
      getAllocationRequest_result result = new getAllocationRequest_result();
      receiveBase(result, "getAllocationRequest");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllocationRequest failed: unknown result");
    }

    public boolean updateAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) throws org.apache.thrift.TException
    {
      send_updateAllocationRequest(allocDetail);
      return recv_updateAllocationRequest();
    }

    public void send_updateAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) throws org.apache.thrift.TException
    {
      updateAllocationRequest_args args = new updateAllocationRequest_args();
      args.setAllocDetail(allocDetail);
      sendBase("updateAllocationRequest", args);
    }

    public boolean recv_updateAllocationRequest() throws org.apache.thrift.TException
    {
      updateAllocationRequest_result result = new updateAllocationRequest_result();
      receiveBase(result, "updateAllocationRequest");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateAllocationRequest failed: unknown result");
    }

    public java.lang.String getAllocationRequestStatus(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      send_getAllocationRequestStatus(projectId, userName);
      return recv_getAllocationRequestStatus();
    }

    public void send_getAllocationRequestStatus(java.lang.String projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      getAllocationRequestStatus_args args = new getAllocationRequestStatus_args();
      args.setProjectId(projectId);
      args.setUserName(userName);
      sendBase("getAllocationRequestStatus", args);
    }

    public java.lang.String recv_getAllocationRequestStatus() throws org.apache.thrift.TException
    {
      getAllocationRequestStatus_result result = new getAllocationRequestStatus_result();
      receiveBase(result, "getAllocationRequestStatus");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllocationRequestStatus failed: unknown result");
    }

    public java.lang.String getAllocationRequestUserEmail(java.lang.String userName) throws org.apache.thrift.TException
    {
      send_getAllocationRequestUserEmail(userName);
      return recv_getAllocationRequestUserEmail();
    }

    public void send_getAllocationRequestUserEmail(java.lang.String userName) throws org.apache.thrift.TException
    {
      getAllocationRequestUserEmail_args args = new getAllocationRequestUserEmail_args();
      args.setUserName(userName);
      sendBase("getAllocationRequestUserEmail", args);
    }

    public java.lang.String recv_getAllocationRequestUserEmail() throws org.apache.thrift.TException
    {
      getAllocationRequestUserEmail_result result = new getAllocationRequestUserEmail_result();
      receiveBase(result, "getAllocationRequestUserEmail");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllocationRequestUserEmail failed: unknown result");
    }

    public java.lang.String getAllocationManagerAdminEmail(java.lang.String userType) throws org.apache.thrift.TException
    {
      send_getAllocationManagerAdminEmail(userType);
      return recv_getAllocationManagerAdminEmail();
    }

    public void send_getAllocationManagerAdminEmail(java.lang.String userType) throws org.apache.thrift.TException
    {
      getAllocationManagerAdminEmail_args args = new getAllocationManagerAdminEmail_args();
      args.setUserType(userType);
      sendBase("getAllocationManagerAdminEmail", args);
    }

    public java.lang.String recv_getAllocationManagerAdminEmail() throws org.apache.thrift.TException
    {
      getAllocationManagerAdminEmail_result result = new getAllocationManagerAdminEmail_result();
      receiveBase(result, "getAllocationManagerAdminEmail");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllocationManagerAdminEmail failed: unknown result");
    }

    public java.lang.String getAllocationRequestUserName(java.lang.String projectId) throws org.apache.thrift.TException
    {
      send_getAllocationRequestUserName(projectId);
      return recv_getAllocationRequestUserName();
    }

    public void send_getAllocationRequestUserName(java.lang.String projectId) throws org.apache.thrift.TException
    {
      getAllocationRequestUserName_args args = new getAllocationRequestUserName_args();
      args.setProjectId(projectId);
      sendBase("getAllocationRequestUserName", args);
    }

    public java.lang.String recv_getAllocationRequestUserName() throws org.apache.thrift.TException
    {
      getAllocationRequestUserName_result result = new getAllocationRequestUserName_result();
      receiveBase(result, "getAllocationRequestUserName");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllocationRequestUserName failed: unknown result");
    }

    public void updateAllocationRequestStatus(java.lang.String projectId, java.lang.String status) throws org.apache.thrift.TException
    {
      send_updateAllocationRequestStatus(projectId, status);
      recv_updateAllocationRequestStatus();
    }

    public void send_updateAllocationRequestStatus(java.lang.String projectId, java.lang.String status) throws org.apache.thrift.TException
    {
      updateAllocationRequestStatus_args args = new updateAllocationRequestStatus_args();
      args.setProjectId(projectId);
      args.setStatus(status);
      sendBase("updateAllocationRequestStatus", args);
    }

    public void recv_updateAllocationRequestStatus() throws org.apache.thrift.TException
    {
      updateAllocationRequestStatus_result result = new updateAllocationRequestStatus_result();
      receiveBase(result, "updateAllocationRequestStatus");
      return;
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getAllRequestsForAdmin(java.lang.String userName) throws org.apache.thrift.TException
    {
      send_getAllRequestsForAdmin(userName);
      return recv_getAllRequestsForAdmin();
    }

    public void send_getAllRequestsForAdmin(java.lang.String userName) throws org.apache.thrift.TException
    {
      getAllRequestsForAdmin_args args = new getAllRequestsForAdmin_args();
      args.setUserName(userName);
      sendBase("getAllRequestsForAdmin", args);
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> recv_getAllRequestsForAdmin() throws org.apache.thrift.TException
    {
      getAllRequestsForAdmin_result result = new getAllRequestsForAdmin_result();
      receiveBase(result, "getAllRequestsForAdmin");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllRequestsForAdmin failed: unknown result");
    }

    public boolean assignReviewers(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      send_assignReviewers(projectId, userName);
      return recv_assignReviewers();
    }

    public void send_assignReviewers(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, java.lang.String userName) throws org.apache.thrift.TException
    {
      assignReviewers_args args = new assignReviewers_args();
      args.setProjectId(projectId);
      args.setUserName(userName);
      sendBase("assignReviewers", args);
    }

    public boolean recv_assignReviewers() throws org.apache.thrift.TException
    {
      assignReviewers_result result = new assignReviewers_result();
      receiveBase(result, "assignReviewers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "assignReviewers failed: unknown result");
    }

    public boolean updateRequestByReviewer(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail) throws org.apache.thrift.TException
    {
      send_updateRequestByReviewer(projectId, userAllocationDetail);
      return recv_updateRequestByReviewer();
    }

    public void send_updateRequestByReviewer(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail) throws org.apache.thrift.TException
    {
      updateRequestByReviewer_args args = new updateRequestByReviewer_args();
      args.setProjectId(projectId);
      args.setUserAllocationDetail(userAllocationDetail);
      sendBase("updateRequestByReviewer", args);
    }

    public boolean recv_updateRequestByReviewer() throws org.apache.thrift.TException
    {
      updateRequestByReviewer_result result = new updateRequestByReviewer_result();
      receiveBase(result, "updateRequestByReviewer");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateRequestByReviewer failed: unknown result");
    }

    public boolean isAdmin(java.lang.String userName) throws org.apache.thrift.TException
    {
      send_isAdmin(userName);
      return recv_isAdmin();
    }

    public void send_isAdmin(java.lang.String userName) throws org.apache.thrift.TException
    {
      isAdmin_args args = new isAdmin_args();
      args.setUserName(userName);
      sendBase("isAdmin", args);
    }

    public boolean recv_isAdmin() throws org.apache.thrift.TException
    {
      isAdmin_result result = new isAdmin_result();
      receiveBase(result, "isAdmin");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isAdmin failed: unknown result");
    }

    public boolean isReviewer(java.lang.String userName) throws org.apache.thrift.TException
    {
      send_isReviewer(userName);
      return recv_isReviewer();
    }

    public void send_isReviewer(java.lang.String userName) throws org.apache.thrift.TException
    {
      isReviewer_args args = new isReviewer_args();
      args.setUserName(userName);
      sendBase("isReviewer", args);
    }

    public boolean recv_isReviewer() throws org.apache.thrift.TException
    {
      isReviewer_result result = new isReviewer_result();
      receiveBase(result, "isReviewer");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isReviewer failed: unknown result");
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getAllRequestsForReviewers(java.lang.String userName) throws org.apache.thrift.TException
    {
      send_getAllRequestsForReviewers(userName);
      return recv_getAllRequestsForReviewers();
    }

    public void send_getAllRequestsForReviewers(java.lang.String userName) throws org.apache.thrift.TException
    {
      getAllRequestsForReviewers_args args = new getAllRequestsForReviewers_args();
      args.setUserName(userName);
      sendBase("getAllRequestsForReviewers", args);
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> recv_getAllRequestsForReviewers() throws org.apache.thrift.TException
    {
      getAllRequestsForReviewers_result result = new getAllRequestsForReviewers_result();
      receiveBase(result, "getAllRequestsForReviewers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllRequestsForReviewers failed: unknown result");
    }

    public org.apache.airavata.allocation.manager.models.UserDetail getUserDetails(java.lang.String userName) throws org.apache.thrift.TException
    {
      send_getUserDetails(userName);
      return recv_getUserDetails();
    }

    public void send_getUserDetails(java.lang.String userName) throws org.apache.thrift.TException
    {
      getUserDetails_args args = new getUserDetails_args();
      args.setUserName(userName);
      sendBase("getUserDetails", args);
    }

    public org.apache.airavata.allocation.manager.models.UserDetail recv_getUserDetails() throws org.apache.thrift.TException
    {
      getUserDetails_result result = new getUserDetails_result();
      receiveBase(result, "getUserDetails");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUserDetails failed: unknown result");
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getReviewsForRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId) throws org.apache.thrift.TException
    {
      send_getReviewsForRequest(projectId);
      return recv_getReviewsForRequest();
    }

    public void send_getReviewsForRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId) throws org.apache.thrift.TException
    {
      getReviewsForRequest_args args = new getReviewsForRequest_args();
      args.setProjectId(projectId);
      sendBase("getReviewsForRequest", args);
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> recv_getReviewsForRequest() throws org.apache.thrift.TException
    {
      getReviewsForRequest_result result = new getReviewsForRequest_result();
      receiveBase(result, "getReviewsForRequest");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getReviewsForRequest failed: unknown result");
    }

  }
  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
      private org.apache.thrift.async.TAsyncClientManager clientManager;
      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
        this.clientManager = clientManager;
        this.protocolFactory = protocolFactory;
      }
      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
        return new AsyncClient(protocolFactory, clientManager, transport);
      }
    }

    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
      super(protocolFactory, clientManager, transport);
    }

    public void createAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createAllocationRequest_call method_call = new createAllocationRequest_call(allocDetail, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createAllocationRequest_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail;
      public createAllocationRequest_call(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.allocDetail = allocDetail;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createAllocationRequest", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createAllocationRequest_args args = new createAllocationRequest_args();
        args.setAllocDetail(allocDetail);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createAllocationRequest();
      }
    }

    public void isAllocationRequestExists(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isAllocationRequestExists_call method_call = new isAllocationRequestExists_call(projectId, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isAllocationRequestExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String projectId;
      private java.lang.String userName;
      public isAllocationRequestExists_call(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isAllocationRequestExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isAllocationRequestExists_args args = new isAllocationRequestExists_args();
        args.setProjectId(projectId);
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isAllocationRequestExists();
      }
    }

    public void deleteAllocationRequest(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteAllocationRequest_call method_call = new deleteAllocationRequest_call(projectId, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteAllocationRequest_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String projectId;
      private java.lang.String userName;
      public deleteAllocationRequest_call(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteAllocationRequest", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteAllocationRequest_args args = new deleteAllocationRequest_args();
        args.setProjectId(projectId);
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteAllocationRequest();
      }
    }

    public void getAllocationRequest(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserAllocationDetail> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllocationRequest_call method_call = new getAllocationRequest_call(projectId, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllocationRequest_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.allocation.manager.models.UserAllocationDetail> {
      private java.lang.String projectId;
      private java.lang.String userName;
      public getAllocationRequest_call(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserAllocationDetail> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllocationRequest", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllocationRequest_args args = new getAllocationRequest_args();
        args.setProjectId(projectId);
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.allocation.manager.models.UserAllocationDetail getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllocationRequest();
      }
    }

    public void updateAllocationRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateAllocationRequest_call method_call = new updateAllocationRequest_call(allocDetail, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateAllocationRequest_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail;
      public updateAllocationRequest_call(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.allocDetail = allocDetail;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateAllocationRequest", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateAllocationRequest_args args = new updateAllocationRequest_args();
        args.setAllocDetail(allocDetail);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateAllocationRequest();
      }
    }

    public void getAllocationRequestStatus(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllocationRequestStatus_call method_call = new getAllocationRequestStatus_call(projectId, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllocationRequestStatus_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private java.lang.String projectId;
      private java.lang.String userName;
      public getAllocationRequestStatus_call(java.lang.String projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllocationRequestStatus", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllocationRequestStatus_args args = new getAllocationRequestStatus_args();
        args.setProjectId(projectId);
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllocationRequestStatus();
      }
    }

    public void getAllocationRequestUserEmail(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllocationRequestUserEmail_call method_call = new getAllocationRequestUserEmail_call(userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllocationRequestUserEmail_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private java.lang.String userName;
      public getAllocationRequestUserEmail_call(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllocationRequestUserEmail", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllocationRequestUserEmail_args args = new getAllocationRequestUserEmail_args();
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllocationRequestUserEmail();
      }
    }

    public void getAllocationManagerAdminEmail(java.lang.String userType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllocationManagerAdminEmail_call method_call = new getAllocationManagerAdminEmail_call(userType, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllocationManagerAdminEmail_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private java.lang.String userType;
      public getAllocationManagerAdminEmail_call(java.lang.String userType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userType = userType;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllocationManagerAdminEmail", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllocationManagerAdminEmail_args args = new getAllocationManagerAdminEmail_args();
        args.setUserType(userType);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllocationManagerAdminEmail();
      }
    }

    public void getAllocationRequestUserName(java.lang.String projectId, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllocationRequestUserName_call method_call = new getAllocationRequestUserName_call(projectId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllocationRequestUserName_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private java.lang.String projectId;
      public getAllocationRequestUserName_call(java.lang.String projectId, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllocationRequestUserName", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllocationRequestUserName_args args = new getAllocationRequestUserName_args();
        args.setProjectId(projectId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllocationRequestUserName();
      }
    }

    public void updateAllocationRequestStatus(java.lang.String projectId, java.lang.String status, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateAllocationRequestStatus_call method_call = new updateAllocationRequestStatus_call(projectId, status, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateAllocationRequestStatus_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
      private java.lang.String projectId;
      private java.lang.String status;
      public updateAllocationRequestStatus_call(java.lang.String projectId, java.lang.String status, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.status = status;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateAllocationRequestStatus", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateAllocationRequestStatus_args args = new updateAllocationRequestStatus_args();
        args.setProjectId(projectId);
        args.setStatus(status);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public Void getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return null;
      }
    }

    public void getAllRequestsForAdmin(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllRequestsForAdmin_call method_call = new getAllRequestsForAdmin_call(userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllRequestsForAdmin_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> {
      private java.lang.String userName;
      public getAllRequestsForAdmin_call(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllRequestsForAdmin", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllRequestsForAdmin_args args = new getAllRequestsForAdmin_args();
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllRequestsForAdmin();
      }
    }

    public void assignReviewers(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      assignReviewers_call method_call = new assignReviewers_call(projectId, userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class assignReviewers_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId;
      private java.lang.String userName;
      public assignReviewers_call(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("assignReviewers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        assignReviewers_args args = new assignReviewers_args();
        args.setProjectId(projectId);
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_assignReviewers();
      }
    }

    public void updateRequestByReviewer(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateRequestByReviewer_call method_call = new updateRequestByReviewer_call(projectId, userAllocationDetail, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateRequestByReviewer_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId;
      private org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail;
      public updateRequestByReviewer_call(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
        this.userAllocationDetail = userAllocationDetail;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateRequestByReviewer", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateRequestByReviewer_args args = new updateRequestByReviewer_args();
        args.setProjectId(projectId);
        args.setUserAllocationDetail(userAllocationDetail);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateRequestByReviewer();
      }
    }

    public void isAdmin(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isAdmin_call method_call = new isAdmin_call(userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isAdmin_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String userName;
      public isAdmin_call(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isAdmin", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isAdmin_args args = new isAdmin_args();
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isAdmin();
      }
    }

    public void isReviewer(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isReviewer_call method_call = new isReviewer_call(userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isReviewer_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String userName;
      public isReviewer_call(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isReviewer", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isReviewer_args args = new isReviewer_args();
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isReviewer();
      }
    }

    public void getAllRequestsForReviewers(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllRequestsForReviewers_call method_call = new getAllRequestsForReviewers_call(userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllRequestsForReviewers_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> {
      private java.lang.String userName;
      public getAllRequestsForReviewers_call(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllRequestsForReviewers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllRequestsForReviewers_args args = new getAllRequestsForReviewers_args();
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllRequestsForReviewers();
      }
    }

    public void getUserDetails(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserDetail> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUserDetails_call method_call = new getUserDetails_call(userName, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getUserDetails_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.allocation.manager.models.UserDetail> {
      private java.lang.String userName;
      public getUserDetails_call(java.lang.String userName, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserDetail> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.userName = userName;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUserDetails", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getUserDetails_args args = new getUserDetails_args();
        args.setUserName(userName);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.allocation.manager.models.UserDetail getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUserDetails();
      }
    }

    public void getReviewsForRequest(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getReviewsForRequest_call method_call = new getReviewsForRequest_call(projectId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getReviewsForRequest_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> {
      private org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId;
      public getReviewsForRequest_call(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.projectId = projectId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getReviewsForRequest", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getReviewsForRequest_args args = new getReviewsForRequest_args();
        args.setProjectId(projectId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getReviewsForRequest();
      }
    }

  }

  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
    public Processor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
    }

    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      processMap.put("createAllocationRequest", new createAllocationRequest());
      processMap.put("isAllocationRequestExists", new isAllocationRequestExists());
      processMap.put("deleteAllocationRequest", new deleteAllocationRequest());
      processMap.put("getAllocationRequest", new getAllocationRequest());
      processMap.put("updateAllocationRequest", new updateAllocationRequest());
      processMap.put("getAllocationRequestStatus", new getAllocationRequestStatus());
      processMap.put("getAllocationRequestUserEmail", new getAllocationRequestUserEmail());
      processMap.put("getAllocationManagerAdminEmail", new getAllocationManagerAdminEmail());
      processMap.put("getAllocationRequestUserName", new getAllocationRequestUserName());
      processMap.put("updateAllocationRequestStatus", new updateAllocationRequestStatus());
      processMap.put("getAllRequestsForAdmin", new getAllRequestsForAdmin());
      processMap.put("assignReviewers", new assignReviewers());
      processMap.put("updateRequestByReviewer", new updateRequestByReviewer());
      processMap.put("isAdmin", new isAdmin());
      processMap.put("isReviewer", new isReviewer());
      processMap.put("getAllRequestsForReviewers", new getAllRequestsForReviewers());
      processMap.put("getUserDetails", new getUserDetails());
      processMap.put("getReviewsForRequest", new getReviewsForRequest());
      return processMap;
    }

    public static class createAllocationRequest<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createAllocationRequest_args> {
      public createAllocationRequest() {
        super("createAllocationRequest");
      }

      public createAllocationRequest_args getEmptyArgsInstance() {
        return new createAllocationRequest_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createAllocationRequest_result getResult(I iface, createAllocationRequest_args args) throws org.apache.thrift.TException {
        createAllocationRequest_result result = new createAllocationRequest_result();
        result.success = iface.createAllocationRequest(args.allocDetail);
        return result;
      }
    }

    public static class isAllocationRequestExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isAllocationRequestExists_args> {
      public isAllocationRequestExists() {
        super("isAllocationRequestExists");
      }

      public isAllocationRequestExists_args getEmptyArgsInstance() {
        return new isAllocationRequestExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isAllocationRequestExists_result getResult(I iface, isAllocationRequestExists_args args) throws org.apache.thrift.TException {
        isAllocationRequestExists_result result = new isAllocationRequestExists_result();
        result.success = iface.isAllocationRequestExists(args.projectId, args.userName);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class deleteAllocationRequest<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteAllocationRequest_args> {
      public deleteAllocationRequest() {
        super("deleteAllocationRequest");
      }

      public deleteAllocationRequest_args getEmptyArgsInstance() {
        return new deleteAllocationRequest_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteAllocationRequest_result getResult(I iface, deleteAllocationRequest_args args) throws org.apache.thrift.TException {
        deleteAllocationRequest_result result = new deleteAllocationRequest_result();
        result.success = iface.deleteAllocationRequest(args.projectId, args.userName);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class getAllocationRequest<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllocationRequest_args> {
      public getAllocationRequest() {
        super("getAllocationRequest");
      }

      public getAllocationRequest_args getEmptyArgsInstance() {
        return new getAllocationRequest_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllocationRequest_result getResult(I iface, getAllocationRequest_args args) throws org.apache.thrift.TException {
        getAllocationRequest_result result = new getAllocationRequest_result();
        result.success = iface.getAllocationRequest(args.projectId, args.userName);
        return result;
      }
    }

    public static class updateAllocationRequest<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateAllocationRequest_args> {
      public updateAllocationRequest() {
        super("updateAllocationRequest");
      }

      public updateAllocationRequest_args getEmptyArgsInstance() {
        return new updateAllocationRequest_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateAllocationRequest_result getResult(I iface, updateAllocationRequest_args args) throws org.apache.thrift.TException {
        updateAllocationRequest_result result = new updateAllocationRequest_result();
        result.success = iface.updateAllocationRequest(args.allocDetail);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class getAllocationRequestStatus<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllocationRequestStatus_args> {
      public getAllocationRequestStatus() {
        super("getAllocationRequestStatus");
      }

      public getAllocationRequestStatus_args getEmptyArgsInstance() {
        return new getAllocationRequestStatus_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllocationRequestStatus_result getResult(I iface, getAllocationRequestStatus_args args) throws org.apache.thrift.TException {
        getAllocationRequestStatus_result result = new getAllocationRequestStatus_result();
        result.success = iface.getAllocationRequestStatus(args.projectId, args.userName);
        return result;
      }
    }

    public static class getAllocationRequestUserEmail<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllocationRequestUserEmail_args> {
      public getAllocationRequestUserEmail() {
        super("getAllocationRequestUserEmail");
      }

      public getAllocationRequestUserEmail_args getEmptyArgsInstance() {
        return new getAllocationRequestUserEmail_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllocationRequestUserEmail_result getResult(I iface, getAllocationRequestUserEmail_args args) throws org.apache.thrift.TException {
        getAllocationRequestUserEmail_result result = new getAllocationRequestUserEmail_result();
        result.success = iface.getAllocationRequestUserEmail(args.userName);
        return result;
      }
    }

    public static class getAllocationManagerAdminEmail<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllocationManagerAdminEmail_args> {
      public getAllocationManagerAdminEmail() {
        super("getAllocationManagerAdminEmail");
      }

      public getAllocationManagerAdminEmail_args getEmptyArgsInstance() {
        return new getAllocationManagerAdminEmail_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllocationManagerAdminEmail_result getResult(I iface, getAllocationManagerAdminEmail_args args) throws org.apache.thrift.TException {
        getAllocationManagerAdminEmail_result result = new getAllocationManagerAdminEmail_result();
        result.success = iface.getAllocationManagerAdminEmail(args.userType);
        return result;
      }
    }

    public static class getAllocationRequestUserName<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllocationRequestUserName_args> {
      public getAllocationRequestUserName() {
        super("getAllocationRequestUserName");
      }

      public getAllocationRequestUserName_args getEmptyArgsInstance() {
        return new getAllocationRequestUserName_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllocationRequestUserName_result getResult(I iface, getAllocationRequestUserName_args args) throws org.apache.thrift.TException {
        getAllocationRequestUserName_result result = new getAllocationRequestUserName_result();
        result.success = iface.getAllocationRequestUserName(args.projectId);
        return result;
      }
    }

    public static class updateAllocationRequestStatus<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateAllocationRequestStatus_args> {
      public updateAllocationRequestStatus() {
        super("updateAllocationRequestStatus");
      }

      public updateAllocationRequestStatus_args getEmptyArgsInstance() {
        return new updateAllocationRequestStatus_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateAllocationRequestStatus_result getResult(I iface, updateAllocationRequestStatus_args args) throws org.apache.thrift.TException {
        updateAllocationRequestStatus_result result = new updateAllocationRequestStatus_result();
        iface.updateAllocationRequestStatus(args.projectId, args.status);
        return result;
      }
    }

    public static class getAllRequestsForAdmin<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllRequestsForAdmin_args> {
      public getAllRequestsForAdmin() {
        super("getAllRequestsForAdmin");
      }

      public getAllRequestsForAdmin_args getEmptyArgsInstance() {
        return new getAllRequestsForAdmin_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllRequestsForAdmin_result getResult(I iface, getAllRequestsForAdmin_args args) throws org.apache.thrift.TException {
        getAllRequestsForAdmin_result result = new getAllRequestsForAdmin_result();
        result.success = iface.getAllRequestsForAdmin(args.userName);
        return result;
      }
    }

    public static class assignReviewers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, assignReviewers_args> {
      public assignReviewers() {
        super("assignReviewers");
      }

      public assignReviewers_args getEmptyArgsInstance() {
        return new assignReviewers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public assignReviewers_result getResult(I iface, assignReviewers_args args) throws org.apache.thrift.TException {
        assignReviewers_result result = new assignReviewers_result();
        result.success = iface.assignReviewers(args.projectId, args.userName);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class updateRequestByReviewer<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateRequestByReviewer_args> {
      public updateRequestByReviewer() {
        super("updateRequestByReviewer");
      }

      public updateRequestByReviewer_args getEmptyArgsInstance() {
        return new updateRequestByReviewer_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateRequestByReviewer_result getResult(I iface, updateRequestByReviewer_args args) throws org.apache.thrift.TException {
        updateRequestByReviewer_result result = new updateRequestByReviewer_result();
        result.success = iface.updateRequestByReviewer(args.projectId, args.userAllocationDetail);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class isAdmin<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isAdmin_args> {
      public isAdmin() {
        super("isAdmin");
      }

      public isAdmin_args getEmptyArgsInstance() {
        return new isAdmin_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isAdmin_result getResult(I iface, isAdmin_args args) throws org.apache.thrift.TException {
        isAdmin_result result = new isAdmin_result();
        result.success = iface.isAdmin(args.userName);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class isReviewer<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isReviewer_args> {
      public isReviewer() {
        super("isReviewer");
      }

      public isReviewer_args getEmptyArgsInstance() {
        return new isReviewer_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isReviewer_result getResult(I iface, isReviewer_args args) throws org.apache.thrift.TException {
        isReviewer_result result = new isReviewer_result();
        result.success = iface.isReviewer(args.userName);
        result.setSuccessIsSet(true);
        return result;
      }
    }

    public static class getAllRequestsForReviewers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllRequestsForReviewers_args> {
      public getAllRequestsForReviewers() {
        super("getAllRequestsForReviewers");
      }

      public getAllRequestsForReviewers_args getEmptyArgsInstance() {
        return new getAllRequestsForReviewers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllRequestsForReviewers_result getResult(I iface, getAllRequestsForReviewers_args args) throws org.apache.thrift.TException {
        getAllRequestsForReviewers_result result = new getAllRequestsForReviewers_result();
        result.success = iface.getAllRequestsForReviewers(args.userName);
        return result;
      }
    }

    public static class getUserDetails<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getUserDetails_args> {
      public getUserDetails() {
        super("getUserDetails");
      }

      public getUserDetails_args getEmptyArgsInstance() {
        return new getUserDetails_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getUserDetails_result getResult(I iface, getUserDetails_args args) throws org.apache.thrift.TException {
        getUserDetails_result result = new getUserDetails_result();
        result.success = iface.getUserDetails(args.userName);
        return result;
      }
    }

    public static class getReviewsForRequest<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getReviewsForRequest_args> {
      public getReviewsForRequest() {
        super("getReviewsForRequest");
      }

      public getReviewsForRequest_args getEmptyArgsInstance() {
        return new getReviewsForRequest_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getReviewsForRequest_result getResult(I iface, getReviewsForRequest_args args) throws org.apache.thrift.TException {
        getReviewsForRequest_result result = new getReviewsForRequest_result();
        result.success = iface.getReviewsForRequest(args.projectId);
        return result;
      }
    }

  }

  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
    public AsyncProcessor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
    }

    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      processMap.put("createAllocationRequest", new createAllocationRequest());
      processMap.put("isAllocationRequestExists", new isAllocationRequestExists());
      processMap.put("deleteAllocationRequest", new deleteAllocationRequest());
      processMap.put("getAllocationRequest", new getAllocationRequest());
      processMap.put("updateAllocationRequest", new updateAllocationRequest());
      processMap.put("getAllocationRequestStatus", new getAllocationRequestStatus());
      processMap.put("getAllocationRequestUserEmail", new getAllocationRequestUserEmail());
      processMap.put("getAllocationManagerAdminEmail", new getAllocationManagerAdminEmail());
      processMap.put("getAllocationRequestUserName", new getAllocationRequestUserName());
      processMap.put("updateAllocationRequestStatus", new updateAllocationRequestStatus());
      processMap.put("getAllRequestsForAdmin", new getAllRequestsForAdmin());
      processMap.put("assignReviewers", new assignReviewers());
      processMap.put("updateRequestByReviewer", new updateRequestByReviewer());
      processMap.put("isAdmin", new isAdmin());
      processMap.put("isReviewer", new isReviewer());
      processMap.put("getAllRequestsForReviewers", new getAllRequestsForReviewers());
      processMap.put("getUserDetails", new getUserDetails());
      processMap.put("getReviewsForRequest", new getReviewsForRequest());
      return processMap;
    }

    public static class createAllocationRequest<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createAllocationRequest_args, java.lang.String> {
      public createAllocationRequest() {
        super("createAllocationRequest");
      }

      public createAllocationRequest_args getEmptyArgsInstance() {
        return new createAllocationRequest_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createAllocationRequest_result result = new createAllocationRequest_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createAllocationRequest_result result = new createAllocationRequest_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createAllocationRequest_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createAllocationRequest(args.allocDetail,resultHandler);
      }
    }

    public static class isAllocationRequestExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isAllocationRequestExists_args, java.lang.Boolean> {
      public isAllocationRequestExists() {
        super("isAllocationRequestExists");
      }

      public isAllocationRequestExists_args getEmptyArgsInstance() {
        return new isAllocationRequestExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isAllocationRequestExists_result result = new isAllocationRequestExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isAllocationRequestExists_result result = new isAllocationRequestExists_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isAllocationRequestExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isAllocationRequestExists(args.projectId, args.userName,resultHandler);
      }
    }

    public static class deleteAllocationRequest<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteAllocationRequest_args, java.lang.Boolean> {
      public deleteAllocationRequest() {
        super("deleteAllocationRequest");
      }

      public deleteAllocationRequest_args getEmptyArgsInstance() {
        return new deleteAllocationRequest_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteAllocationRequest_result result = new deleteAllocationRequest_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteAllocationRequest_result result = new deleteAllocationRequest_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteAllocationRequest_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteAllocationRequest(args.projectId, args.userName,resultHandler);
      }
    }

    public static class getAllocationRequest<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllocationRequest_args, org.apache.airavata.allocation.manager.models.UserAllocationDetail> {
      public getAllocationRequest() {
        super("getAllocationRequest");
      }

      public getAllocationRequest_args getEmptyArgsInstance() {
        return new getAllocationRequest_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserAllocationDetail>() { 
          public void onComplete(org.apache.airavata.allocation.manager.models.UserAllocationDetail o) {
            getAllocationRequest_result result = new getAllocationRequest_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllocationRequest_result result = new getAllocationRequest_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllocationRequest_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserAllocationDetail> resultHandler) throws org.apache.thrift.TException {
        iface.getAllocationRequest(args.projectId, args.userName,resultHandler);
      }
    }

    public static class updateAllocationRequest<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateAllocationRequest_args, java.lang.Boolean> {
      public updateAllocationRequest() {
        super("updateAllocationRequest");
      }

      public updateAllocationRequest_args getEmptyArgsInstance() {
        return new updateAllocationRequest_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateAllocationRequest_result result = new updateAllocationRequest_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateAllocationRequest_result result = new updateAllocationRequest_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateAllocationRequest_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateAllocationRequest(args.allocDetail,resultHandler);
      }
    }

    public static class getAllocationRequestStatus<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllocationRequestStatus_args, java.lang.String> {
      public getAllocationRequestStatus() {
        super("getAllocationRequestStatus");
      }

      public getAllocationRequestStatus_args getEmptyArgsInstance() {
        return new getAllocationRequestStatus_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            getAllocationRequestStatus_result result = new getAllocationRequestStatus_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllocationRequestStatus_result result = new getAllocationRequestStatus_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllocationRequestStatus_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.getAllocationRequestStatus(args.projectId, args.userName,resultHandler);
      }
    }

    public static class getAllocationRequestUserEmail<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllocationRequestUserEmail_args, java.lang.String> {
      public getAllocationRequestUserEmail() {
        super("getAllocationRequestUserEmail");
      }

      public getAllocationRequestUserEmail_args getEmptyArgsInstance() {
        return new getAllocationRequestUserEmail_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            getAllocationRequestUserEmail_result result = new getAllocationRequestUserEmail_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllocationRequestUserEmail_result result = new getAllocationRequestUserEmail_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllocationRequestUserEmail_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.getAllocationRequestUserEmail(args.userName,resultHandler);
      }
    }

    public static class getAllocationManagerAdminEmail<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllocationManagerAdminEmail_args, java.lang.String> {
      public getAllocationManagerAdminEmail() {
        super("getAllocationManagerAdminEmail");
      }

      public getAllocationManagerAdminEmail_args getEmptyArgsInstance() {
        return new getAllocationManagerAdminEmail_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            getAllocationManagerAdminEmail_result result = new getAllocationManagerAdminEmail_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllocationManagerAdminEmail_result result = new getAllocationManagerAdminEmail_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllocationManagerAdminEmail_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.getAllocationManagerAdminEmail(args.userType,resultHandler);
      }
    }

    public static class getAllocationRequestUserName<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllocationRequestUserName_args, java.lang.String> {
      public getAllocationRequestUserName() {
        super("getAllocationRequestUserName");
      }

      public getAllocationRequestUserName_args getEmptyArgsInstance() {
        return new getAllocationRequestUserName_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            getAllocationRequestUserName_result result = new getAllocationRequestUserName_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllocationRequestUserName_result result = new getAllocationRequestUserName_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllocationRequestUserName_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.getAllocationRequestUserName(args.projectId,resultHandler);
      }
    }

    public static class updateAllocationRequestStatus<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateAllocationRequestStatus_args, Void> {
      public updateAllocationRequestStatus() {
        super("updateAllocationRequestStatus");
      }

      public updateAllocationRequestStatus_args getEmptyArgsInstance() {
        return new updateAllocationRequestStatus_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
          public void onComplete(Void o) {
            updateAllocationRequestStatus_result result = new updateAllocationRequestStatus_result();
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateAllocationRequestStatus_result result = new updateAllocationRequestStatus_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateAllocationRequestStatus_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
        iface.updateAllocationRequestStatus(args.projectId, args.status,resultHandler);
      }
    }

    public static class getAllRequestsForAdmin<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllRequestsForAdmin_args, java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> {
      public getAllRequestsForAdmin() {
        super("getAllRequestsForAdmin");
      }

      public getAllRequestsForAdmin_args getEmptyArgsInstance() {
        return new getAllRequestsForAdmin_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>>() { 
          public void onComplete(java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> o) {
            getAllRequestsForAdmin_result result = new getAllRequestsForAdmin_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllRequestsForAdmin_result result = new getAllRequestsForAdmin_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllRequestsForAdmin_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException {
        iface.getAllRequestsForAdmin(args.userName,resultHandler);
      }
    }

    public static class assignReviewers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, assignReviewers_args, java.lang.Boolean> {
      public assignReviewers() {
        super("assignReviewers");
      }

      public assignReviewers_args getEmptyArgsInstance() {
        return new assignReviewers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            assignReviewers_result result = new assignReviewers_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            assignReviewers_result result = new assignReviewers_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, assignReviewers_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.assignReviewers(args.projectId, args.userName,resultHandler);
      }
    }

    public static class updateRequestByReviewer<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateRequestByReviewer_args, java.lang.Boolean> {
      public updateRequestByReviewer() {
        super("updateRequestByReviewer");
      }

      public updateRequestByReviewer_args getEmptyArgsInstance() {
        return new updateRequestByReviewer_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateRequestByReviewer_result result = new updateRequestByReviewer_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateRequestByReviewer_result result = new updateRequestByReviewer_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateRequestByReviewer_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateRequestByReviewer(args.projectId, args.userAllocationDetail,resultHandler);
      }
    }

    public static class isAdmin<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isAdmin_args, java.lang.Boolean> {
      public isAdmin() {
        super("isAdmin");
      }

      public isAdmin_args getEmptyArgsInstance() {
        return new isAdmin_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isAdmin_result result = new isAdmin_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isAdmin_result result = new isAdmin_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isAdmin_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isAdmin(args.userName,resultHandler);
      }
    }

    public static class isReviewer<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isReviewer_args, java.lang.Boolean> {
      public isReviewer() {
        super("isReviewer");
      }

      public isReviewer_args getEmptyArgsInstance() {
        return new isReviewer_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isReviewer_result result = new isReviewer_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isReviewer_result result = new isReviewer_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isReviewer_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isReviewer(args.userName,resultHandler);
      }
    }

    public static class getAllRequestsForReviewers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllRequestsForReviewers_args, java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> {
      public getAllRequestsForReviewers() {
        super("getAllRequestsForReviewers");
      }

      public getAllRequestsForReviewers_args getEmptyArgsInstance() {
        return new getAllRequestsForReviewers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>>() { 
          public void onComplete(java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> o) {
            getAllRequestsForReviewers_result result = new getAllRequestsForReviewers_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllRequestsForReviewers_result result = new getAllRequestsForReviewers_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllRequestsForReviewers_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException {
        iface.getAllRequestsForReviewers(args.userName,resultHandler);
      }
    }

    public static class getUserDetails<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUserDetails_args, org.apache.airavata.allocation.manager.models.UserDetail> {
      public getUserDetails() {
        super("getUserDetails");
      }

      public getUserDetails_args getEmptyArgsInstance() {
        return new getUserDetails_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserDetail> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserDetail>() { 
          public void onComplete(org.apache.airavata.allocation.manager.models.UserDetail o) {
            getUserDetails_result result = new getUserDetails_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getUserDetails_result result = new getUserDetails_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUserDetails_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.allocation.manager.models.UserDetail> resultHandler) throws org.apache.thrift.TException {
        iface.getUserDetails(args.userName,resultHandler);
      }
    }

    public static class getReviewsForRequest<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getReviewsForRequest_args, java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> {
      public getReviewsForRequest() {
        super("getReviewsForRequest");
      }

      public getReviewsForRequest_args getEmptyArgsInstance() {
        return new getReviewsForRequest_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>>() { 
          public void onComplete(java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> o) {
            getReviewsForRequest_result result = new getReviewsForRequest_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getReviewsForRequest_result result = new getReviewsForRequest_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getReviewsForRequest_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>> resultHandler) throws org.apache.thrift.TException {
        iface.getReviewsForRequest(args.projectId,resultHandler);
      }
    }

  }

  public static class createAllocationRequest_args implements org.apache.thrift.TBase<createAllocationRequest_args, createAllocationRequest_args._Fields>, java.io.Serializable, Cloneable, Comparable<createAllocationRequest_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createAllocationRequest_args");

    private static final org.apache.thrift.protocol.TField ALLOC_DETAIL_FIELD_DESC = new org.apache.thrift.protocol.TField("allocDetail", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail; // 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 {
      ALLOC_DETAIL((short)1, "allocDetail");

      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: // ALLOC_DETAIL
            return ALLOC_DETAIL;
          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
    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.ALLOC_DETAIL, new org.apache.thrift.meta_data.FieldMetaData("allocDetail", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createAllocationRequest_args.class, metaDataMap);
    }

    public createAllocationRequest_args() {
    }

    public createAllocationRequest_args(
      org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail)
    {
      this();
      this.allocDetail = allocDetail;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createAllocationRequest_args(createAllocationRequest_args other) {
      if (other.isSetAllocDetail()) {
        this.allocDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other.allocDetail);
      }
    }

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

    @Override
    public void clear() {
      this.allocDetail = null;
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail getAllocDetail() {
      return this.allocDetail;
    }

    public createAllocationRequest_args setAllocDetail(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) {
      this.allocDetail = allocDetail;
      return this;
    }

    public void unsetAllocDetail() {
      this.allocDetail = null;
    }

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

    public void setAllocDetailIsSet(boolean value) {
      if (!value) {
        this.allocDetail = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ALLOC_DETAIL:
        if (value == null) {
          unsetAllocDetail();
        } else {
          setAllocDetail((org.apache.airavata.allocation.manager.models.UserAllocationDetail)value);
        }
        break;

      }
    }

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

      }
      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 ALLOC_DETAIL:
        return isSetAllocDetail();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_allocDetail = true && this.isSetAllocDetail();
      boolean that_present_allocDetail = true && that.isSetAllocDetail();
      if (this_present_allocDetail || that_present_allocDetail) {
        if (!(this_present_allocDetail && that_present_allocDetail))
          return false;
        if (!this.allocDetail.equals(that.allocDetail))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetAllocDetail()) ? 131071 : 524287);
      if (isSetAllocDetail())
        hashCode = hashCode * 8191 + allocDetail.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAllocDetail()).compareTo(other.isSetAllocDetail());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAllocDetail()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.allocDetail, other.allocDetail);
        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("createAllocationRequest_args(");
      boolean first = true;

      sb.append("allocDetail:");
      if (this.allocDetail == null) {
        sb.append("null");
      } else {
        sb.append(this.allocDetail);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (allocDetail == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'allocDetail' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (allocDetail != null) {
        allocDetail.validate();
      }
    }

    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 {
        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 createAllocationRequest_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createAllocationRequest_argsStandardScheme getScheme() {
        return new createAllocationRequest_argsStandardScheme();
      }
    }

    private static class createAllocationRequest_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createAllocationRequest_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createAllocationRequest_args 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: // ALLOC_DETAIL
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.allocDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                struct.allocDetail.read(iprot);
                struct.setAllocDetailIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.allocDetail != null) {
          oprot.writeFieldBegin(ALLOC_DETAIL_FIELD_DESC);
          struct.allocDetail.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createAllocationRequest_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createAllocationRequest_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.allocDetail.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.allocDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
        struct.allocDetail.read(iprot);
        struct.setAllocDetailIsSet(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();
    }
  }

  public static class createAllocationRequest_result implements org.apache.thrift.TBase<createAllocationRequest_result, createAllocationRequest_result._Fields>, java.io.Serializable, Cloneable, Comparable<createAllocationRequest_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createAllocationRequest_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

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

    public java.lang.String success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createAllocationRequest_result.class, metaDataMap);
    }

    public createAllocationRequest_result() {
    }

    public createAllocationRequest_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createAllocationRequest_result(createAllocationRequest_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createAllocationRequest_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

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

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("createAllocationRequest_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 createAllocationRequest_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createAllocationRequest_resultStandardScheme getScheme() {
        return new createAllocationRequest_resultStandardScheme();
      }
    }

    private static class createAllocationRequest_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createAllocationRequest_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createAllocationRequest_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createAllocationRequest_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createAllocationRequest_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(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();
    }
  }

  public static class isAllocationRequestExists_args implements org.apache.thrift.TBase<isAllocationRequestExists_args, isAllocationRequestExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<isAllocationRequestExists_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isAllocationRequestExists_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String projectId; // required
    public java.lang.String userName; // 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 {
      PROJECT_ID((short)1, "projectId"),
      USER_NAME((short)2, "userName");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // USER_NAME
            return USER_NAME;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isAllocationRequestExists_args.class, metaDataMap);
    }

    public isAllocationRequestExists_args() {
    }

    public isAllocationRequestExists_args(
      java.lang.String projectId,
      java.lang.String userName)
    {
      this();
      this.projectId = projectId;
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isAllocationRequestExists_args(isAllocationRequestExists_args other) {
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.userName = null;
    }

    public java.lang.String getProjectId() {
      return this.projectId;
    }

    public isAllocationRequestExists_args setProjectId(java.lang.String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public isAllocationRequestExists_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_NAME:
        return getUserName();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("isAllocationRequestExists_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 isAllocationRequestExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isAllocationRequestExists_argsStandardScheme getScheme() {
        return new isAllocationRequestExists_argsStandardScheme();
      }
    }

    private static class isAllocationRequestExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isAllocationRequestExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isAllocationRequestExists_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isAllocationRequestExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isAllocationRequestExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isAllocationRequestExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.projectId);
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isAllocationRequestExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class isAllocationRequestExists_result implements org.apache.thrift.TBase<isAllocationRequestExists_result, isAllocationRequestExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<isAllocationRequestExists_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isAllocationRequestExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isAllocationRequestExists_result.class, metaDataMap);
    }

    public isAllocationRequestExists_result() {
    }

    public isAllocationRequestExists_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isAllocationRequestExists_result(isAllocationRequestExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isAllocationRequestExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("isAllocationRequestExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 isAllocationRequestExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isAllocationRequestExists_resultStandardScheme getScheme() {
        return new isAllocationRequestExists_resultStandardScheme();
      }
    }

    private static class isAllocationRequestExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isAllocationRequestExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isAllocationRequestExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isAllocationRequestExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isAllocationRequestExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isAllocationRequestExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isAllocationRequestExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class deleteAllocationRequest_args implements org.apache.thrift.TBase<deleteAllocationRequest_args, deleteAllocationRequest_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteAllocationRequest_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteAllocationRequest_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String projectId; // required
    public java.lang.String userName; // 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 {
      PROJECT_ID((short)1, "projectId"),
      USER_NAME((short)2, "userName");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // USER_NAME
            return USER_NAME;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteAllocationRequest_args.class, metaDataMap);
    }

    public deleteAllocationRequest_args() {
    }

    public deleteAllocationRequest_args(
      java.lang.String projectId,
      java.lang.String userName)
    {
      this();
      this.projectId = projectId;
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteAllocationRequest_args(deleteAllocationRequest_args other) {
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.userName = null;
    }

    public java.lang.String getProjectId() {
      return this.projectId;
    }

    public deleteAllocationRequest_args setProjectId(java.lang.String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public deleteAllocationRequest_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_NAME:
        return getUserName();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("deleteAllocationRequest_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 deleteAllocationRequest_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteAllocationRequest_argsStandardScheme getScheme() {
        return new deleteAllocationRequest_argsStandardScheme();
      }
    }

    private static class deleteAllocationRequest_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteAllocationRequest_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteAllocationRequest_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class deleteAllocationRequest_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteAllocationRequest_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.projectId);
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class deleteAllocationRequest_result implements org.apache.thrift.TBase<deleteAllocationRequest_result, deleteAllocationRequest_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteAllocationRequest_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteAllocationRequest_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteAllocationRequest_result.class, metaDataMap);
    }

    public deleteAllocationRequest_result() {
    }

    public deleteAllocationRequest_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteAllocationRequest_result(deleteAllocationRequest_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteAllocationRequest_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("deleteAllocationRequest_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 deleteAllocationRequest_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteAllocationRequest_resultStandardScheme getScheme() {
        return new deleteAllocationRequest_resultStandardScheme();
      }
    }

    private static class deleteAllocationRequest_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteAllocationRequest_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteAllocationRequest_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class deleteAllocationRequest_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteAllocationRequest_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class getAllocationRequest_args implements org.apache.thrift.TBase<getAllocationRequest_args, getAllocationRequest_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequest_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequest_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String projectId; // required
    public java.lang.String userName; // 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 {
      PROJECT_ID((short)1, "projectId"),
      USER_NAME((short)2, "userName");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // USER_NAME
            return USER_NAME;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequest_args.class, metaDataMap);
    }

    public getAllocationRequest_args() {
    }

    public getAllocationRequest_args(
      java.lang.String projectId,
      java.lang.String userName)
    {
      this();
      this.projectId = projectId;
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequest_args(getAllocationRequest_args other) {
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.userName = null;
    }

    public java.lang.String getProjectId() {
      return this.projectId;
    }

    public getAllocationRequest_args setProjectId(java.lang.String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public getAllocationRequest_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_NAME:
        return getUserName();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("getAllocationRequest_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 getAllocationRequest_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequest_argsStandardScheme getScheme() {
        return new getAllocationRequest_argsStandardScheme();
      }
    }

    private static class getAllocationRequest_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequest_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequest_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequest_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequest_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.projectId);
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class getAllocationRequest_result implements org.apache.thrift.TBase<getAllocationRequest_result, getAllocationRequest_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequest_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequest_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);

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

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequest_result.class, metaDataMap);
    }

    public getAllocationRequest_result() {
    }

    public getAllocationRequest_result(
      org.apache.airavata.allocation.manager.models.UserAllocationDetail success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequest_result(getAllocationRequest_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other.success);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail getSuccess() {
      return this.success;
    }

    public getAllocationRequest_result setSuccess(org.apache.airavata.allocation.manager.models.UserAllocationDetail success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.allocation.manager.models.UserAllocationDetail)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllocationRequest_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 {
        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 getAllocationRequest_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequest_resultStandardScheme getScheme() {
        return new getAllocationRequest_resultStandardScheme();
      }
    }

    private static class getAllocationRequest_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequest_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequest_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                struct.success.read(iprot);
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequest_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequest_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
          struct.success.read(iprot);
          struct.setSuccessIsSet(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();
    }
  }

  public static class updateAllocationRequest_args implements org.apache.thrift.TBase<updateAllocationRequest_args, updateAllocationRequest_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateAllocationRequest_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateAllocationRequest_args");

    private static final org.apache.thrift.protocol.TField ALLOC_DETAIL_FIELD_DESC = new org.apache.thrift.protocol.TField("allocDetail", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail; // 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 {
      ALLOC_DETAIL((short)1, "allocDetail");

      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: // ALLOC_DETAIL
            return ALLOC_DETAIL;
          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
    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.ALLOC_DETAIL, new org.apache.thrift.meta_data.FieldMetaData("allocDetail", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAllocationRequest_args.class, metaDataMap);
    }

    public updateAllocationRequest_args() {
    }

    public updateAllocationRequest_args(
      org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail)
    {
      this();
      this.allocDetail = allocDetail;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateAllocationRequest_args(updateAllocationRequest_args other) {
      if (other.isSetAllocDetail()) {
        this.allocDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other.allocDetail);
      }
    }

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

    @Override
    public void clear() {
      this.allocDetail = null;
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail getAllocDetail() {
      return this.allocDetail;
    }

    public updateAllocationRequest_args setAllocDetail(org.apache.airavata.allocation.manager.models.UserAllocationDetail allocDetail) {
      this.allocDetail = allocDetail;
      return this;
    }

    public void unsetAllocDetail() {
      this.allocDetail = null;
    }

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

    public void setAllocDetailIsSet(boolean value) {
      if (!value) {
        this.allocDetail = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ALLOC_DETAIL:
        if (value == null) {
          unsetAllocDetail();
        } else {
          setAllocDetail((org.apache.airavata.allocation.manager.models.UserAllocationDetail)value);
        }
        break;

      }
    }

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

      }
      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 ALLOC_DETAIL:
        return isSetAllocDetail();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_allocDetail = true && this.isSetAllocDetail();
      boolean that_present_allocDetail = true && that.isSetAllocDetail();
      if (this_present_allocDetail || that_present_allocDetail) {
        if (!(this_present_allocDetail && that_present_allocDetail))
          return false;
        if (!this.allocDetail.equals(that.allocDetail))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetAllocDetail()) ? 131071 : 524287);
      if (isSetAllocDetail())
        hashCode = hashCode * 8191 + allocDetail.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetAllocDetail()).compareTo(other.isSetAllocDetail());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAllocDetail()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.allocDetail, other.allocDetail);
        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("updateAllocationRequest_args(");
      boolean first = true;

      sb.append("allocDetail:");
      if (this.allocDetail == null) {
        sb.append("null");
      } else {
        sb.append(this.allocDetail);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (allocDetail == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'allocDetail' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (allocDetail != null) {
        allocDetail.validate();
      }
    }

    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 {
        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 updateAllocationRequest_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAllocationRequest_argsStandardScheme getScheme() {
        return new updateAllocationRequest_argsStandardScheme();
      }
    }

    private static class updateAllocationRequest_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateAllocationRequest_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateAllocationRequest_args 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: // ALLOC_DETAIL
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.allocDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                struct.allocDetail.read(iprot);
                struct.setAllocDetailIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.allocDetail != null) {
          oprot.writeFieldBegin(ALLOC_DETAIL_FIELD_DESC);
          struct.allocDetail.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateAllocationRequest_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateAllocationRequest_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.allocDetail.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.allocDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
        struct.allocDetail.read(iprot);
        struct.setAllocDetailIsSet(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();
    }
  }

  public static class updateAllocationRequest_result implements org.apache.thrift.TBase<updateAllocationRequest_result, updateAllocationRequest_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateAllocationRequest_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateAllocationRequest_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAllocationRequest_result.class, metaDataMap);
    }

    public updateAllocationRequest_result() {
    }

    public updateAllocationRequest_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateAllocationRequest_result(updateAllocationRequest_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateAllocationRequest_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("updateAllocationRequest_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 updateAllocationRequest_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAllocationRequest_resultStandardScheme getScheme() {
        return new updateAllocationRequest_resultStandardScheme();
      }
    }

    private static class updateAllocationRequest_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateAllocationRequest_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateAllocationRequest_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateAllocationRequest_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateAllocationRequest_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class getAllocationRequestStatus_args implements org.apache.thrift.TBase<getAllocationRequestStatus_args, getAllocationRequestStatus_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequestStatus_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequestStatus_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String projectId; // required
    public java.lang.String userName; // 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 {
      PROJECT_ID((short)1, "projectId"),
      USER_NAME((short)2, "userName");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // USER_NAME
            return USER_NAME;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequestStatus_args.class, metaDataMap);
    }

    public getAllocationRequestStatus_args() {
    }

    public getAllocationRequestStatus_args(
      java.lang.String projectId,
      java.lang.String userName)
    {
      this();
      this.projectId = projectId;
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequestStatus_args(getAllocationRequestStatus_args other) {
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.userName = null;
    }

    public java.lang.String getProjectId() {
      return this.projectId;
    }

    public getAllocationRequestStatus_args setProjectId(java.lang.String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public getAllocationRequestStatus_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_NAME:
        return getUserName();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("getAllocationRequestStatus_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 getAllocationRequestStatus_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequestStatus_argsStandardScheme getScheme() {
        return new getAllocationRequestStatus_argsStandardScheme();
      }
    }

    private static class getAllocationRequestStatus_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequestStatus_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequestStatus_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequestStatus_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequestStatus_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestStatus_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.projectId);
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestStatus_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class getAllocationRequestStatus_result implements org.apache.thrift.TBase<getAllocationRequestStatus_result, getAllocationRequestStatus_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequestStatus_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequestStatus_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

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

    public java.lang.String success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequestStatus_result.class, metaDataMap);
    }

    public getAllocationRequestStatus_result() {
    }

    public getAllocationRequestStatus_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequestStatus_result(getAllocationRequestStatus_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public getAllocationRequestStatus_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

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

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllocationRequestStatus_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getAllocationRequestStatus_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequestStatus_resultStandardScheme getScheme() {
        return new getAllocationRequestStatus_resultStandardScheme();
      }
    }

    private static class getAllocationRequestStatus_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequestStatus_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequestStatus_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequestStatus_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequestStatus_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestStatus_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestStatus_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(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();
    }
  }

  public static class getAllocationRequestUserEmail_args implements org.apache.thrift.TBase<getAllocationRequestUserEmail_args, getAllocationRequestUserEmail_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequestUserEmail_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequestUserEmail_args");

    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userName; // 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 {
      USER_NAME((short)1, "userName");

      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: // USER_NAME
            return USER_NAME;
          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
    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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequestUserEmail_args.class, metaDataMap);
    }

    public getAllocationRequestUserEmail_args() {
    }

    public getAllocationRequestUserEmail_args(
      java.lang.String userName)
    {
      this();
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequestUserEmail_args(getAllocationRequestUserEmail_args other) {
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.userName = null;
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public getAllocationRequestUserEmail_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      }
    }

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

      }
      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 USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("getAllocationRequestUserEmail_args(");
      boolean first = true;

      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 getAllocationRequestUserEmail_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequestUserEmail_argsStandardScheme getScheme() {
        return new getAllocationRequestUserEmail_argsStandardScheme();
      }
    }

    private static class getAllocationRequestUserEmail_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequestUserEmail_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequestUserEmail_args 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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequestUserEmail_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequestUserEmail_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserEmail_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserEmail_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class getAllocationRequestUserEmail_result implements org.apache.thrift.TBase<getAllocationRequestUserEmail_result, getAllocationRequestUserEmail_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequestUserEmail_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequestUserEmail_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

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

    public java.lang.String success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequestUserEmail_result.class, metaDataMap);
    }

    public getAllocationRequestUserEmail_result() {
    }

    public getAllocationRequestUserEmail_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequestUserEmail_result(getAllocationRequestUserEmail_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public getAllocationRequestUserEmail_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

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

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllocationRequestUserEmail_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getAllocationRequestUserEmail_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequestUserEmail_resultStandardScheme getScheme() {
        return new getAllocationRequestUserEmail_resultStandardScheme();
      }
    }

    private static class getAllocationRequestUserEmail_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequestUserEmail_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequestUserEmail_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequestUserEmail_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequestUserEmail_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserEmail_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserEmail_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(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();
    }
  }

  public static class getAllocationManagerAdminEmail_args implements org.apache.thrift.TBase<getAllocationManagerAdminEmail_args, getAllocationManagerAdminEmail_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationManagerAdminEmail_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationManagerAdminEmail_args");

    private static final org.apache.thrift.protocol.TField USER_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("userType", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userType; // 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 {
      USER_TYPE((short)1, "userType");

      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: // USER_TYPE
            return USER_TYPE;
          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
    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.USER_TYPE, new org.apache.thrift.meta_data.FieldMetaData("userType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationManagerAdminEmail_args.class, metaDataMap);
    }

    public getAllocationManagerAdminEmail_args() {
    }

    public getAllocationManagerAdminEmail_args(
      java.lang.String userType)
    {
      this();
      this.userType = userType;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationManagerAdminEmail_args(getAllocationManagerAdminEmail_args other) {
      if (other.isSetUserType()) {
        this.userType = other.userType;
      }
    }

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

    @Override
    public void clear() {
      this.userType = null;
    }

    public java.lang.String getUserType() {
      return this.userType;
    }

    public getAllocationManagerAdminEmail_args setUserType(java.lang.String userType) {
      this.userType = userType;
      return this;
    }

    public void unsetUserType() {
      this.userType = null;
    }

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

    public void setUserTypeIsSet(boolean value) {
      if (!value) {
        this.userType = null;
      }
    }

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

      }
    }

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

      }
      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 USER_TYPE:
        return isSetUserType();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userType = true && this.isSetUserType();
      boolean that_present_userType = true && that.isSetUserType();
      if (this_present_userType || that_present_userType) {
        if (!(this_present_userType && that_present_userType))
          return false;
        if (!this.userType.equals(that.userType))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserType()) ? 131071 : 524287);
      if (isSetUserType())
        hashCode = hashCode * 8191 + userType.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserType()).compareTo(other.isSetUserType());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserType()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userType, other.userType);
        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("getAllocationManagerAdminEmail_args(");
      boolean first = true;

      sb.append("userType:");
      if (this.userType == null) {
        sb.append("null");
      } else {
        sb.append(this.userType);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userType == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userType' was not present! 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 {
        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 getAllocationManagerAdminEmail_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationManagerAdminEmail_argsStandardScheme getScheme() {
        return new getAllocationManagerAdminEmail_argsStandardScheme();
      }
    }

    private static class getAllocationManagerAdminEmail_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationManagerAdminEmail_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationManagerAdminEmail_args 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: // USER_TYPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userType = iprot.readString();
                struct.setUserTypeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userType != null) {
          oprot.writeFieldBegin(USER_TYPE_FIELD_DESC);
          oprot.writeString(struct.userType);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationManagerAdminEmail_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationManagerAdminEmail_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationManagerAdminEmail_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userType);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationManagerAdminEmail_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userType = iprot.readString();
        struct.setUserTypeIsSet(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();
    }
  }

  public static class getAllocationManagerAdminEmail_result implements org.apache.thrift.TBase<getAllocationManagerAdminEmail_result, getAllocationManagerAdminEmail_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationManagerAdminEmail_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationManagerAdminEmail_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

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

    public java.lang.String success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationManagerAdminEmail_result.class, metaDataMap);
    }

    public getAllocationManagerAdminEmail_result() {
    }

    public getAllocationManagerAdminEmail_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationManagerAdminEmail_result(getAllocationManagerAdminEmail_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public getAllocationManagerAdminEmail_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

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

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllocationManagerAdminEmail_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getAllocationManagerAdminEmail_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationManagerAdminEmail_resultStandardScheme getScheme() {
        return new getAllocationManagerAdminEmail_resultStandardScheme();
      }
    }

    private static class getAllocationManagerAdminEmail_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationManagerAdminEmail_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationManagerAdminEmail_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationManagerAdminEmail_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationManagerAdminEmail_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationManagerAdminEmail_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationManagerAdminEmail_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(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();
    }
  }

  public static class getAllocationRequestUserName_args implements org.apache.thrift.TBase<getAllocationRequestUserName_args, getAllocationRequestUserName_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequestUserName_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequestUserName_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String projectId; // 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 {
      PROJECT_ID((short)1, "projectId");

      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: // PROJECT_ID
            return PROJECT_ID;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequestUserName_args.class, metaDataMap);
    }

    public getAllocationRequestUserName_args() {
    }

    public getAllocationRequestUserName_args(
      java.lang.String projectId)
    {
      this();
      this.projectId = projectId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequestUserName_args(getAllocationRequestUserName_args other) {
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
    }

    public java.lang.String getProjectId() {
      return this.projectId;
    }

    public getAllocationRequestUserName_args setProjectId(java.lang.String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

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

      }
    }

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

      }
      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 PROJECT_ID:
        return isSetProjectId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        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("getAllocationRequestUserName_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! 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 {
        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 getAllocationRequestUserName_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequestUserName_argsStandardScheme getScheme() {
        return new getAllocationRequestUserName_argsStandardScheme();
      }
    }

    private static class getAllocationRequestUserName_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequestUserName_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequestUserName_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequestUserName_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequestUserName_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserName_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.projectId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserName_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(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();
    }
  }

  public static class getAllocationRequestUserName_result implements org.apache.thrift.TBase<getAllocationRequestUserName_result, getAllocationRequestUserName_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllocationRequestUserName_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllocationRequestUserName_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);

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

    public java.lang.String success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllocationRequestUserName_result.class, metaDataMap);
    }

    public getAllocationRequestUserName_result() {
    }

    public getAllocationRequestUserName_result(
      java.lang.String success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllocationRequestUserName_result(getAllocationRequestUserName_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public getAllocationRequestUserName_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

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

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllocationRequestUserName_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getAllocationRequestUserName_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllocationRequestUserName_resultStandardScheme getScheme() {
        return new getAllocationRequestUserName_resultStandardScheme();
      }
    }

    private static class getAllocationRequestUserName_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllocationRequestUserName_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllocationRequestUserName_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllocationRequestUserName_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllocationRequestUserName_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserName_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllocationRequestUserName_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(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();
    }
  }

  public static class updateAllocationRequestStatus_args implements org.apache.thrift.TBase<updateAllocationRequestStatus_args, updateAllocationRequestStatus_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateAllocationRequestStatus_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateAllocationRequestStatus_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String projectId; // required
    public java.lang.String status; // 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 {
      PROJECT_ID((short)1, "projectId"),
      STATUS((short)2, "status");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // STATUS
            return STATUS;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAllocationRequestStatus_args.class, metaDataMap);
    }

    public updateAllocationRequestStatus_args() {
    }

    public updateAllocationRequestStatus_args(
      java.lang.String projectId,
      java.lang.String status)
    {
      this();
      this.projectId = projectId;
      this.status = status;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateAllocationRequestStatus_args(updateAllocationRequestStatus_args other) {
      if (other.isSetProjectId()) {
        this.projectId = other.projectId;
      }
      if (other.isSetStatus()) {
        this.status = other.status;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.status = null;
    }

    public java.lang.String getProjectId() {
      return this.projectId;
    }

    public updateAllocationRequestStatus_args setProjectId(java.lang.String projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public java.lang.String getStatus() {
      return this.status;
    }

    public updateAllocationRequestStatus_args setStatus(java.lang.String status) {
      this.status = status;
      return this;
    }

    public void unsetStatus() {
      this.status = null;
    }

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

    public void setStatusIsSet(boolean value) {
      if (!value) {
        this.status = null;
      }
    }

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

      case STATUS:
        if (value == null) {
          unsetStatus();
        } else {
          setStatus((java.lang.String)value);
        }
        break;

      }
    }

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

      case STATUS:
        return getStatus();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case STATUS:
        return isSetStatus();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_status = true && this.isSetStatus();
      boolean that_present_status = true && that.isSetStatus();
      if (this_present_status || that_present_status) {
        if (!(this_present_status && that_present_status))
          return false;
        if (!this.status.equals(that.status))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetStatus()) ? 131071 : 524287);
      if (isSetStatus())
        hashCode = hashCode * 8191 + status.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetStatus()).compareTo(other.isSetStatus());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetStatus()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.status, other.status);
        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("updateAllocationRequestStatus_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("status:");
      if (this.status == null) {
        sb.append("null");
      } else {
        sb.append(this.status);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (status == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'status' was not present! 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 {
        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 updateAllocationRequestStatus_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAllocationRequestStatus_argsStandardScheme getScheme() {
        return new updateAllocationRequestStatus_argsStandardScheme();
      }
    }

    private static class updateAllocationRequestStatus_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateAllocationRequestStatus_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateAllocationRequestStatus_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.projectId = iprot.readString();
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // STATUS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.status = iprot.readString();
                struct.setStatusIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
        if (struct.status != null) {
          oprot.writeFieldBegin(STATUS_FIELD_DESC);
          oprot.writeString(struct.status);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateAllocationRequestStatus_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateAllocationRequestStatus_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequestStatus_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.projectId);
        oprot.writeString(struct.status);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequestStatus_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
        struct.status = iprot.readString();
        struct.setStatusIsSet(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();
    }
  }

  public static class updateAllocationRequestStatus_result implements org.apache.thrift.TBase<updateAllocationRequestStatus_result, updateAllocationRequestStatus_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateAllocationRequestStatus_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateAllocationRequestStatus_result");


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


    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
;

      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) {
          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;
      }
    }
    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);
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAllocationRequestStatus_result.class, metaDataMap);
    }

    public updateAllocationRequestStatus_result() {
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateAllocationRequestStatus_result(updateAllocationRequestStatus_result other) {
    }

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

    @Override
    public void clear() {
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      }
      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) {
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      return true;
    }

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

      return hashCode;
    }

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

      int lastComparison = 0;

      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("updateAllocationRequestStatus_result(");
      boolean first = true;

      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 updateAllocationRequestStatus_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateAllocationRequestStatus_resultStandardScheme getScheme() {
        return new updateAllocationRequestStatus_resultStandardScheme();
      }
    }

    private static class updateAllocationRequestStatus_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateAllocationRequestStatus_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateAllocationRequestStatus_result 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) {
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateAllocationRequestStatus_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateAllocationRequestStatus_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequestStatus_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateAllocationRequestStatus_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      }
    }

    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();
    }
  }

  public static class getAllRequestsForAdmin_args implements org.apache.thrift.TBase<getAllRequestsForAdmin_args, getAllRequestsForAdmin_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllRequestsForAdmin_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllRequestsForAdmin_args");

    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userName; // 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 {
      USER_NAME((short)1, "userName");

      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: // USER_NAME
            return USER_NAME;
          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
    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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllRequestsForAdmin_args.class, metaDataMap);
    }

    public getAllRequestsForAdmin_args() {
    }

    public getAllRequestsForAdmin_args(
      java.lang.String userName)
    {
      this();
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllRequestsForAdmin_args(getAllRequestsForAdmin_args other) {
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.userName = null;
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public getAllRequestsForAdmin_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      }
    }

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

      }
      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 USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("getAllRequestsForAdmin_args(");
      boolean first = true;

      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 getAllRequestsForAdmin_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllRequestsForAdmin_argsStandardScheme getScheme() {
        return new getAllRequestsForAdmin_argsStandardScheme();
      }
    }

    private static class getAllRequestsForAdmin_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllRequestsForAdmin_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllRequestsForAdmin_args 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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllRequestsForAdmin_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllRequestsForAdmin_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForAdmin_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForAdmin_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class getAllRequestsForAdmin_result implements org.apache.thrift.TBase<getAllRequestsForAdmin_result, getAllRequestsForAdmin_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllRequestsForAdmin_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllRequestsForAdmin_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);

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

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllRequestsForAdmin_result.class, metaDataMap);
    }

    public getAllRequestsForAdmin_result() {
    }

    public getAllRequestsForAdmin_result(
      java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllRequestsForAdmin_result(getAllRequestsForAdmin_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> __this__success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(other.success.size());
        for (org.apache.airavata.allocation.manager.models.UserAllocationDetail other_element : other.success) {
          __this__success.add(new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other_element));
        }
        this.success = __this__success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

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

    public java.util.Iterator<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.allocation.manager.models.UserAllocationDetail elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getSuccess() {
      return this.success;
    }

    public getAllRequestsForAdmin_result setSuccess(java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllRequestsForAdmin_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getAllRequestsForAdmin_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllRequestsForAdmin_resultStandardScheme getScheme() {
        return new getAllRequestsForAdmin_resultStandardScheme();
      }
    }

    private static class getAllRequestsForAdmin_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllRequestsForAdmin_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllRequestsForAdmin_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(_list0.size);
                  org.apache.airavata.allocation.manager.models.UserAllocationDetail _elem1;
                  for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                  {
                    _elem1 = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                    _elem1.read(iprot);
                    struct.success.add(_elem1);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.allocation.manager.models.UserAllocationDetail _iter3 : struct.success)
            {
              _iter3.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllRequestsForAdmin_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllRequestsForAdmin_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForAdmin_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.allocation.manager.models.UserAllocationDetail _iter4 : struct.success)
            {
              _iter4.write(oprot);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForAdmin_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(_list5.size);
            org.apache.airavata.allocation.manager.models.UserAllocationDetail _elem6;
            for (int _i7 = 0; _i7 < _list5.size; ++_i7)
            {
              _elem6 = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
              _elem6.read(iprot);
              struct.success.add(_elem6);
            }
          }
          struct.setSuccessIsSet(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();
    }
  }

  public static class assignReviewers_args implements org.apache.thrift.TBase<assignReviewers_args, assignReviewers_args._Fields>, java.io.Serializable, Cloneable, Comparable<assignReviewers_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("assignReviewers_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId; // required
    public java.lang.String userName; // 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 {
      PROJECT_ID((short)1, "projectId"),
      USER_NAME((short)2, "userName");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // USER_NAME
            return USER_NAME;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetailPK.class)));
      tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(assignReviewers_args.class, metaDataMap);
    }

    public assignReviewers_args() {
    }

    public assignReviewers_args(
      org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId,
      java.lang.String userName)
    {
      this();
      this.projectId = projectId;
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public assignReviewers_args(assignReviewers_args other) {
      if (other.isSetProjectId()) {
        this.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK(other.projectId);
      }
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.userName = null;
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetailPK getProjectId() {
      return this.projectId;
    }

    public assignReviewers_args setProjectId(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public assignReviewers_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((org.apache.airavata.allocation.manager.models.UserAllocationDetailPK)value);
        }
        break;

      case USER_NAME:
        if (value == null) {
          unsetUserName();
        } else {
          setUserName((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_NAME:
        return getUserName();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("assignReviewers_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (projectId != null) {
        projectId.validate();
      }
    }

    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 {
        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 assignReviewers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public assignReviewers_argsStandardScheme getScheme() {
        return new assignReviewers_argsStandardScheme();
      }
    }

    private static class assignReviewers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<assignReviewers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, assignReviewers_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK();
                struct.projectId.read(iprot);
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          struct.projectId.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class assignReviewers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<assignReviewers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, assignReviewers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId.write(oprot);
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, assignReviewers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK();
        struct.projectId.read(iprot);
        struct.setProjectIdIsSet(true);
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class assignReviewers_result implements org.apache.thrift.TBase<assignReviewers_result, assignReviewers_result._Fields>, java.io.Serializable, Cloneable, Comparable<assignReviewers_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("assignReviewers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(assignReviewers_result.class, metaDataMap);
    }

    public assignReviewers_result() {
    }

    public assignReviewers_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public assignReviewers_result(assignReviewers_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public assignReviewers_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("assignReviewers_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 assignReviewers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public assignReviewers_resultStandardScheme getScheme() {
        return new assignReviewers_resultStandardScheme();
      }
    }

    private static class assignReviewers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<assignReviewers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, assignReviewers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class assignReviewers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<assignReviewers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, assignReviewers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, assignReviewers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class updateRequestByReviewer_args implements org.apache.thrift.TBase<updateRequestByReviewer_args, updateRequestByReviewer_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateRequestByReviewer_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateRequestByReviewer_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ALLOCATION_DETAIL_FIELD_DESC = new org.apache.thrift.protocol.TField("userAllocationDetail", org.apache.thrift.protocol.TType.STRUCT, (short)2);

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

    public org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId; // required
    public org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail; // 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 {
      PROJECT_ID((short)1, "projectId"),
      USER_ALLOCATION_DETAIL((short)2, "userAllocationDetail");

      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: // PROJECT_ID
            return PROJECT_ID;
          case 2: // USER_ALLOCATION_DETAIL
            return USER_ALLOCATION_DETAIL;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetailPK.class)));
      tmpMap.put(_Fields.USER_ALLOCATION_DETAIL, new org.apache.thrift.meta_data.FieldMetaData("userAllocationDetail", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRequestByReviewer_args.class, metaDataMap);
    }

    public updateRequestByReviewer_args() {
    }

    public updateRequestByReviewer_args(
      org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId,
      org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail)
    {
      this();
      this.projectId = projectId;
      this.userAllocationDetail = userAllocationDetail;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateRequestByReviewer_args(updateRequestByReviewer_args other) {
      if (other.isSetProjectId()) {
        this.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK(other.projectId);
      }
      if (other.isSetUserAllocationDetail()) {
        this.userAllocationDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other.userAllocationDetail);
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
      this.userAllocationDetail = null;
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetailPK getProjectId() {
      return this.projectId;
    }

    public updateRequestByReviewer_args setProjectId(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetail getUserAllocationDetail() {
      return this.userAllocationDetail;
    }

    public updateRequestByReviewer_args setUserAllocationDetail(org.apache.airavata.allocation.manager.models.UserAllocationDetail userAllocationDetail) {
      this.userAllocationDetail = userAllocationDetail;
      return this;
    }

    public void unsetUserAllocationDetail() {
      this.userAllocationDetail = null;
    }

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

    public void setUserAllocationDetailIsSet(boolean value) {
      if (!value) {
        this.userAllocationDetail = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((org.apache.airavata.allocation.manager.models.UserAllocationDetailPK)value);
        }
        break;

      case USER_ALLOCATION_DETAIL:
        if (value == null) {
          unsetUserAllocationDetail();
        } else {
          setUserAllocationDetail((org.apache.airavata.allocation.manager.models.UserAllocationDetail)value);
        }
        break;

      }
    }

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

      case USER_ALLOCATION_DETAIL:
        return getUserAllocationDetail();

      }
      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 PROJECT_ID:
        return isSetProjectId();
      case USER_ALLOCATION_DETAIL:
        return isSetUserAllocationDetail();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      boolean this_present_userAllocationDetail = true && this.isSetUserAllocationDetail();
      boolean that_present_userAllocationDetail = true && that.isSetUserAllocationDetail();
      if (this_present_userAllocationDetail || that_present_userAllocationDetail) {
        if (!(this_present_userAllocationDetail && that_present_userAllocationDetail))
          return false;
        if (!this.userAllocationDetail.equals(that.userAllocationDetail))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserAllocationDetail()) ? 131071 : 524287);
      if (isSetUserAllocationDetail())
        hashCode = hashCode * 8191 + userAllocationDetail.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserAllocationDetail()).compareTo(other.isSetUserAllocationDetail());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserAllocationDetail()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userAllocationDetail, other.userAllocationDetail);
        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("updateRequestByReviewer_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userAllocationDetail:");
      if (this.userAllocationDetail == null) {
        sb.append("null");
      } else {
        sb.append(this.userAllocationDetail);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      if (userAllocationDetail == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userAllocationDetail' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (projectId != null) {
        projectId.validate();
      }
      if (userAllocationDetail != null) {
        userAllocationDetail.validate();
      }
    }

    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 {
        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 updateRequestByReviewer_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRequestByReviewer_argsStandardScheme getScheme() {
        return new updateRequestByReviewer_argsStandardScheme();
      }
    }

    private static class updateRequestByReviewer_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateRequestByReviewer_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateRequestByReviewer_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK();
                struct.projectId.read(iprot);
                struct.setProjectIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ALLOCATION_DETAIL
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.userAllocationDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                struct.userAllocationDetail.read(iprot);
                struct.setUserAllocationDetailIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          struct.projectId.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.userAllocationDetail != null) {
          oprot.writeFieldBegin(USER_ALLOCATION_DETAIL_FIELD_DESC);
          struct.userAllocationDetail.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateRequestByReviewer_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateRequestByReviewer_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateRequestByReviewer_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId.write(oprot);
        struct.userAllocationDetail.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateRequestByReviewer_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK();
        struct.projectId.read(iprot);
        struct.setProjectIdIsSet(true);
        struct.userAllocationDetail = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
        struct.userAllocationDetail.read(iprot);
        struct.setUserAllocationDetailIsSet(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();
    }
  }

  public static class updateRequestByReviewer_result implements org.apache.thrift.TBase<updateRequestByReviewer_result, updateRequestByReviewer_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateRequestByReviewer_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateRequestByReviewer_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRequestByReviewer_result.class, metaDataMap);
    }

    public updateRequestByReviewer_result() {
    }

    public updateRequestByReviewer_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateRequestByReviewer_result(updateRequestByReviewer_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateRequestByReviewer_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("updateRequestByReviewer_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 updateRequestByReviewer_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateRequestByReviewer_resultStandardScheme getScheme() {
        return new updateRequestByReviewer_resultStandardScheme();
      }
    }

    private static class updateRequestByReviewer_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateRequestByReviewer_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateRequestByReviewer_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateRequestByReviewer_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateRequestByReviewer_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateRequestByReviewer_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateRequestByReviewer_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class isAdmin_args implements org.apache.thrift.TBase<isAdmin_args, isAdmin_args._Fields>, java.io.Serializable, Cloneable, Comparable<isAdmin_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isAdmin_args");

    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userName; // 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 {
      USER_NAME((short)1, "userName");

      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: // USER_NAME
            return USER_NAME;
          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
    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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isAdmin_args.class, metaDataMap);
    }

    public isAdmin_args() {
    }

    public isAdmin_args(
      java.lang.String userName)
    {
      this();
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isAdmin_args(isAdmin_args other) {
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.userName = null;
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public isAdmin_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      }
    }

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

      }
      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 USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("isAdmin_args(");
      boolean first = true;

      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 isAdmin_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isAdmin_argsStandardScheme getScheme() {
        return new isAdmin_argsStandardScheme();
      }
    }

    private static class isAdmin_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isAdmin_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isAdmin_args 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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isAdmin_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isAdmin_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isAdmin_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isAdmin_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class isAdmin_result implements org.apache.thrift.TBase<isAdmin_result, isAdmin_result._Fields>, java.io.Serializable, Cloneable, Comparable<isAdmin_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isAdmin_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isAdmin_result.class, metaDataMap);
    }

    public isAdmin_result() {
    }

    public isAdmin_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isAdmin_result(isAdmin_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isAdmin_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("isAdmin_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 isAdmin_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isAdmin_resultStandardScheme getScheme() {
        return new isAdmin_resultStandardScheme();
      }
    }

    private static class isAdmin_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isAdmin_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isAdmin_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isAdmin_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isAdmin_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isAdmin_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isAdmin_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class isReviewer_args implements org.apache.thrift.TBase<isReviewer_args, isReviewer_args._Fields>, java.io.Serializable, Cloneable, Comparable<isReviewer_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isReviewer_args");

    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userName; // 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 {
      USER_NAME((short)1, "userName");

      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: // USER_NAME
            return USER_NAME;
          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
    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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isReviewer_args.class, metaDataMap);
    }

    public isReviewer_args() {
    }

    public isReviewer_args(
      java.lang.String userName)
    {
      this();
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isReviewer_args(isReviewer_args other) {
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.userName = null;
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public isReviewer_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      }
    }

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

      }
      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 USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("isReviewer_args(");
      boolean first = true;

      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 isReviewer_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isReviewer_argsStandardScheme getScheme() {
        return new isReviewer_argsStandardScheme();
      }
    }

    private static class isReviewer_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isReviewer_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isReviewer_args 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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isReviewer_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isReviewer_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isReviewer_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isReviewer_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class isReviewer_result implements org.apache.thrift.TBase<isReviewer_result, isReviewer_result._Fields>, java.io.Serializable, Cloneable, Comparable<isReviewer_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isReviewer_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);

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

    public boolean success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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 __SUCCESS_ISSET_ID = 0;
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isReviewer_result.class, metaDataMap);
    }

    public isReviewer_result() {
    }

    public isReviewer_result(
      boolean success)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isReviewer_result(isReviewer_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isReviewer_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("isReviewer_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 isReviewer_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isReviewer_resultStandardScheme getScheme() {
        return new isReviewer_resultStandardScheme();
      }
    }

    private static class isReviewer_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isReviewer_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isReviewer_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isReviewer_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isReviewer_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isReviewer_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isReviewer_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(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();
    }
  }

  public static class getAllRequestsForReviewers_args implements org.apache.thrift.TBase<getAllRequestsForReviewers_args, getAllRequestsForReviewers_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllRequestsForReviewers_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllRequestsForReviewers_args");

    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userName; // 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 {
      USER_NAME((short)1, "userName");

      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: // USER_NAME
            return USER_NAME;
          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
    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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllRequestsForReviewers_args.class, metaDataMap);
    }

    public getAllRequestsForReviewers_args() {
    }

    public getAllRequestsForReviewers_args(
      java.lang.String userName)
    {
      this();
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllRequestsForReviewers_args(getAllRequestsForReviewers_args other) {
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.userName = null;
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public getAllRequestsForReviewers_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      }
    }

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

      }
      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 USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("getAllRequestsForReviewers_args(");
      boolean first = true;

      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 getAllRequestsForReviewers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllRequestsForReviewers_argsStandardScheme getScheme() {
        return new getAllRequestsForReviewers_argsStandardScheme();
      }
    }

    private static class getAllRequestsForReviewers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllRequestsForReviewers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllRequestsForReviewers_args 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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllRequestsForReviewers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllRequestsForReviewers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForReviewers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForReviewers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class getAllRequestsForReviewers_result implements org.apache.thrift.TBase<getAllRequestsForReviewers_result, getAllRequestsForReviewers_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllRequestsForReviewers_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllRequestsForReviewers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);

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

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllRequestsForReviewers_result.class, metaDataMap);
    }

    public getAllRequestsForReviewers_result() {
    }

    public getAllRequestsForReviewers_result(
      java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllRequestsForReviewers_result(getAllRequestsForReviewers_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> __this__success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(other.success.size());
        for (org.apache.airavata.allocation.manager.models.UserAllocationDetail other_element : other.success) {
          __this__success.add(new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other_element));
        }
        this.success = __this__success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

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

    public java.util.Iterator<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.allocation.manager.models.UserAllocationDetail elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getSuccess() {
      return this.success;
    }

    public getAllRequestsForReviewers_result setSuccess(java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getAllRequestsForReviewers_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getAllRequestsForReviewers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllRequestsForReviewers_resultStandardScheme getScheme() {
        return new getAllRequestsForReviewers_resultStandardScheme();
      }
    }

    private static class getAllRequestsForReviewers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllRequestsForReviewers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllRequestsForReviewers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(_list8.size);
                  org.apache.airavata.allocation.manager.models.UserAllocationDetail _elem9;
                  for (int _i10 = 0; _i10 < _list8.size; ++_i10)
                  {
                    _elem9 = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                    _elem9.read(iprot);
                    struct.success.add(_elem9);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.allocation.manager.models.UserAllocationDetail _iter11 : struct.success)
            {
              _iter11.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getAllRequestsForReviewers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllRequestsForReviewers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForReviewers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.allocation.manager.models.UserAllocationDetail _iter12 : struct.success)
            {
              _iter12.write(oprot);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllRequestsForReviewers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(_list13.size);
            org.apache.airavata.allocation.manager.models.UserAllocationDetail _elem14;
            for (int _i15 = 0; _i15 < _list13.size; ++_i15)
            {
              _elem14 = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
              _elem14.read(iprot);
              struct.success.add(_elem14);
            }
          }
          struct.setSuccessIsSet(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();
    }
  }

  public static class getUserDetails_args implements org.apache.thrift.TBase<getUserDetails_args, getUserDetails_args._Fields>, java.io.Serializable, Cloneable, Comparable<getUserDetails_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserDetails_args");

    private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String userName; // 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 {
      USER_NAME((short)1, "userName");

      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: // USER_NAME
            return USER_NAME;
          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
    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.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserDetails_args.class, metaDataMap);
    }

    public getUserDetails_args() {
    }

    public getUserDetails_args(
      java.lang.String userName)
    {
      this();
      this.userName = userName;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserDetails_args(getUserDetails_args other) {
      if (other.isSetUserName()) {
        this.userName = other.userName;
      }
    }

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

    @Override
    public void clear() {
      this.userName = null;
    }

    public java.lang.String getUserName() {
      return this.userName;
    }

    public getUserDetails_args setUserName(java.lang.String userName) {
      this.userName = userName;
      return this;
    }

    public void unsetUserName() {
      this.userName = null;
    }

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

    public void setUserNameIsSet(boolean value) {
      if (!value) {
        this.userName = null;
      }
    }

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

      }
    }

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

      }
      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 USER_NAME:
        return isSetUserName();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_userName = true && this.isSetUserName();
      boolean that_present_userName = true && that.isSetUserName();
      if (this_present_userName || that_present_userName) {
        if (!(this_present_userName && that_present_userName))
          return false;
        if (!this.userName.equals(that.userName))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
      if (isSetUserName())
        hashCode = hashCode * 8191 + userName.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUserName()).compareTo(other.isSetUserName());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserName()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
        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("getUserDetails_args(");
      boolean first = true;

      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (userName == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userName' was not present! 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 {
        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 getUserDetails_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUserDetails_argsStandardScheme getScheme() {
        return new getUserDetails_argsStandardScheme();
      }
    }

    private static class getUserDetails_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUserDetails_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUserDetails_args 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: // USER_NAME
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userName = iprot.readString();
                struct.setUserNameIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.userName != null) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getUserDetails_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUserDetails_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUserDetails_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.userName);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserDetails_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(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();
    }
  }

  public static class getUserDetails_result implements org.apache.thrift.TBase<getUserDetails_result, getUserDetails_result._Fields>, java.io.Serializable, Cloneable, Comparable<getUserDetails_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getUserDetails_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);

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

    public org.apache.airavata.allocation.manager.models.UserDetail success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserDetail.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserDetails_result.class, metaDataMap);
    }

    public getUserDetails_result() {
    }

    public getUserDetails_result(
      org.apache.airavata.allocation.manager.models.UserDetail success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUserDetails_result(getUserDetails_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.allocation.manager.models.UserDetail(other.success);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

    public org.apache.airavata.allocation.manager.models.UserDetail getSuccess() {
      return this.success;
    }

    public getUserDetails_result setSuccess(org.apache.airavata.allocation.manager.models.UserDetail success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.allocation.manager.models.UserDetail)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getUserDetails_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.validate();
      }
    }

    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 {
        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 getUserDetails_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUserDetails_resultStandardScheme getScheme() {
        return new getUserDetails_resultStandardScheme();
      }
    }

    private static class getUserDetails_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUserDetails_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUserDetails_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.allocation.manager.models.UserDetail();
                struct.success.read(iprot);
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getUserDetails_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUserDetails_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUserDetails_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUserDetails_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.allocation.manager.models.UserDetail();
          struct.success.read(iprot);
          struct.setSuccessIsSet(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();
    }
  }

  public static class getReviewsForRequest_args implements org.apache.thrift.TBase<getReviewsForRequest_args, getReviewsForRequest_args._Fields>, java.io.Serializable, Cloneable, Comparable<getReviewsForRequest_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getReviewsForRequest_args");

    private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId; // 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 {
      PROJECT_ID((short)1, "projectId");

      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: // PROJECT_ID
            return PROJECT_ID;
          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
    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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.allocation.manager.models.UserAllocationDetailPK.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getReviewsForRequest_args.class, metaDataMap);
    }

    public getReviewsForRequest_args() {
    }

    public getReviewsForRequest_args(
      org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId)
    {
      this();
      this.projectId = projectId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getReviewsForRequest_args(getReviewsForRequest_args other) {
      if (other.isSetProjectId()) {
        this.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK(other.projectId);
      }
    }

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

    @Override
    public void clear() {
      this.projectId = null;
    }

    public org.apache.airavata.allocation.manager.models.UserAllocationDetailPK getProjectId() {
      return this.projectId;
    }

    public getReviewsForRequest_args setProjectId(org.apache.airavata.allocation.manager.models.UserAllocationDetailPK projectId) {
      this.projectId = projectId;
      return this;
    }

    public void unsetProjectId() {
      this.projectId = null;
    }

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

    public void setProjectIdIsSet(boolean value) {
      if (!value) {
        this.projectId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case PROJECT_ID:
        if (value == null) {
          unsetProjectId();
        } else {
          setProjectId((org.apache.airavata.allocation.manager.models.UserAllocationDetailPK)value);
        }
        break;

      }
    }

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

      }
      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 PROJECT_ID:
        return isSetProjectId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_projectId = true && this.isSetProjectId();
      boolean that_present_projectId = true && that.isSetProjectId();
      if (this_present_projectId || that_present_projectId) {
        if (!(this_present_projectId && that_present_projectId))
          return false;
        if (!this.projectId.equals(that.projectId))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
      if (isSetProjectId())
        hashCode = hashCode * 8191 + projectId.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetProjectId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
        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("getReviewsForRequest_args(");
      boolean first = true;

      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (projectId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'projectId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (projectId != null) {
        projectId.validate();
      }
    }

    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 {
        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 getReviewsForRequest_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getReviewsForRequest_argsStandardScheme getScheme() {
        return new getReviewsForRequest_argsStandardScheme();
      }
    }

    private static class getReviewsForRequest_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getReviewsForRequest_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getReviewsForRequest_args 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: // PROJECT_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK();
                struct.projectId.read(iprot);
                struct.setProjectIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.projectId != null) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          struct.projectId.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getReviewsForRequest_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getReviewsForRequest_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getReviewsForRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getReviewsForRequest_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.projectId = new org.apache.airavata.allocation.manager.models.UserAllocationDetailPK();
        struct.projectId.read(iprot);
        struct.setProjectIdIsSet(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();
    }
  }

  public static class getReviewsForRequest_result implements org.apache.thrift.TBase<getReviewsForRequest_result, getReviewsForRequest_result._Fields>, java.io.Serializable, Cloneable, Comparable<getReviewsForRequest_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getReviewsForRequest_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);

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

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success; // 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 {
      SUCCESS((short)0, "success");

      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 0: // SUCCESS
            return SUCCESS;
          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
    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.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          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, org.apache.airavata.allocation.manager.models.UserAllocationDetail.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getReviewsForRequest_result.class, metaDataMap);
    }

    public getReviewsForRequest_result() {
    }

    public getReviewsForRequest_result(
      java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getReviewsForRequest_result(getReviewsForRequest_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> __this__success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(other.success.size());
        for (org.apache.airavata.allocation.manager.models.UserAllocationDetail other_element : other.success) {
          __this__success.add(new org.apache.airavata.allocation.manager.models.UserAllocationDetail(other_element));
        }
        this.success = __this__success;
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
    }

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

    public java.util.Iterator<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.allocation.manager.models.UserAllocationDetail elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> getSuccess() {
      return this.success;
    }

    public getReviewsForRequest_result setSuccess(java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.allocation.manager.models.UserAllocationDetail>)value);
        }
        break;

      }
    }

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

      }
      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 SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        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("getReviewsForRequest_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // 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 {
        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 getReviewsForRequest_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getReviewsForRequest_resultStandardScheme getScheme() {
        return new getReviewsForRequest_resultStandardScheme();
      }
    }

    private static class getReviewsForRequest_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getReviewsForRequest_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getReviewsForRequest_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list16 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(_list16.size);
                  org.apache.airavata.allocation.manager.models.UserAllocationDetail _elem17;
                  for (int _i18 = 0; _i18 < _list16.size; ++_i18)
                  {
                    _elem17 = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
                    _elem17.read(iprot);
                    struct.success.add(_elem17);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

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

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.allocation.manager.models.UserAllocationDetail _iter19 : struct.success)
            {
              _iter19.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getReviewsForRequest_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getReviewsForRequest_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getReviewsForRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.allocation.manager.models.UserAllocationDetail _iter20 : struct.success)
            {
              _iter20.write(oprot);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getReviewsForRequest_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list21 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.allocation.manager.models.UserAllocationDetail>(_list21.size);
            org.apache.airavata.allocation.manager.models.UserAllocationDetail _elem22;
            for (int _i23 = 0; _i23 < _list21.size; ++_i23)
            {
              _elem22 = new org.apache.airavata.allocation.manager.models.UserAllocationDetail();
              _elem22.read(iprot);
              struct.success.add(_elem22);
            }
          }
          struct.setSuccessIsSet(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();
    }
  }

}
