/**
 * This code was generated by
 * \ / _    _  _|   _  _
 *  | (_)\/(_)(_|\/| |(/_  v1.0.0
 *       /       /
 */

package com.twilio.rest.taskrouter.v1.workspace.task;

import com.twilio.base.Updater;
import com.twilio.converter.Promoter;
import com.twilio.exception.ApiConnectionException;
import com.twilio.exception.ApiException;
import com.twilio.exception.RestException;
import com.twilio.http.HttpMethod;
import com.twilio.http.Request;
import com.twilio.http.Response;
import com.twilio.http.TwilioRestClient;
import com.twilio.rest.Domains;

import java.net.URI;
import java.util.List;

public class ReservationUpdater extends Updater<Reservation> {
    private final String pathWorkspaceSid;
    private final String pathTaskSid;
    private final String pathSid;
    private Reservation.Status reservationStatus;
    private String workerActivitySid;
    private String instruction;
    private String dequeuePostWorkActivitySid;
    private String dequeueFrom;
    private String dequeueRecord;
    private Integer dequeueTimeout;
    private String dequeueTo;
    private URI dequeueStatusCallbackUrl;
    private String callFrom;
    private String callRecord;
    private Integer callTimeout;
    private String callTo;
    private URI callUrl;
    private URI callStatusCallbackUrl;
    private Boolean callAccept;
    private String redirectCallSid;
    private Boolean redirectAccept;
    private URI redirectUrl;
    private String to;
    private String from;
    private URI statusCallback;
    private HttpMethod statusCallbackMethod;
    private List<Reservation.CallStatus> statusCallbackEvent;
    private Integer timeout;
    private Boolean record;
    private Boolean muted;
    private String beep;
    private Boolean startConferenceOnEnter;
    private Boolean endConferenceOnExit;
    private URI waitUrl;
    private HttpMethod waitMethod;
    private Boolean earlyMedia;
    private Integer maxParticipants;
    private URI conferenceStatusCallback;
    private HttpMethod conferenceStatusCallbackMethod;
    private List<Reservation.ConferenceEvent> conferenceStatusCallbackEvent;
    private String conferenceRecord;
    private String conferenceTrim;
    private String recordingChannels;
    private URI recordingStatusCallback;
    private HttpMethod recordingStatusCallbackMethod;
    private URI conferenceRecordingStatusCallback;
    private HttpMethod conferenceRecordingStatusCallbackMethod;
    private String region;
    private String sipAuthUsername;
    private String sipAuthPassword;
    private List<String> dequeueStatusCallbackEvent;
    private String postWorkActivitySid;
    private Reservation.SupervisorMode supervisorMode;
    private String supervisor;
    private Boolean endConferenceOnCustomerExit;
    private Boolean beepOnCustomerEntrance;
    private String ifMatch;

    /**
     * Construct a new ReservationUpdater.
     *
     * @param pathWorkspaceSid The SID of the Workspace with the TaskReservation
     *                         resources to update
     * @param pathTaskSid The SID of the reserved Task resource with the
     *                    TaskReservation resources to update
     * @param pathSid The SID of the TaskReservation resource to update
     */
    public ReservationUpdater(final String pathWorkspaceSid,
                              final String pathTaskSid,
                              final String pathSid) {
        this.pathWorkspaceSid = pathWorkspaceSid;
        this.pathTaskSid = pathTaskSid;
        this.pathSid = pathSid;
    }

    /**
     * The new status of the reservation. Can be: `pending`, `accepted`, `rejected`,
     * or `timeout`..
     *
     * @param reservationStatus The new status of the reservation
     * @return this
     */
    public ReservationUpdater setReservationStatus(final Reservation.Status reservationStatus) {
        this.reservationStatus = reservationStatus;
        return this;
    }

    /**
     * The new worker activity SID if rejecting a reservation..
     *
     * @param workerActivitySid The new worker activity SID if rejecting a
     *                          reservation
     * @return this
     */
    public ReservationUpdater setWorkerActivitySid(final String workerActivitySid) {
        this.workerActivitySid = workerActivitySid;
        return this;
    }

    /**
     * The assignment instruction for reservation..
     *
     * @param instruction The assignment instruction for reservation
     * @return this
     */
    public ReservationUpdater setInstruction(final String instruction) {
        this.instruction = instruction;
        return this;
    }

    /**
     * The SID of the Activity resource to start after executing a Dequeue
     * instruction..
     *
     * @param dequeuePostWorkActivitySid The SID of the Activity resource to start
     *                                   after executing a Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeuePostWorkActivitySid(final String dequeuePostWorkActivitySid) {
        this.dequeuePostWorkActivitySid = dequeuePostWorkActivitySid;
        return this;
    }

    /**
     * The Caller ID of the call to the worker when executing a Dequeue
     * instruction..
     *
     * @param dequeueFrom The Caller ID of the call to the worker when executing a
     *                    Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueFrom(final String dequeueFrom) {
        this.dequeueFrom = dequeueFrom;
        return this;
    }

    /**
     * Whether to record both legs of a call when executing a Dequeue instruction or
     * which leg to record..
     *
     * @param dequeueRecord Whether to record both legs of a call when executing a
     *                      Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueRecord(final String dequeueRecord) {
        this.dequeueRecord = dequeueRecord;
        return this;
    }

    /**
     * Timeout for call when executing a Dequeue instruction..
     *
     * @param dequeueTimeout Timeout for call when executing a Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueTimeout(final Integer dequeueTimeout) {
        this.dequeueTimeout = dequeueTimeout;
        return this;
    }

    /**
     * The Contact URI of the worker when executing a Dequeue instruction. Can be
     * the URI of the Twilio Client, the SIP URI for Programmable SIP, or the <a
     * href="https://www.twilio.com/docs/glossary/what-e164">E.164</a> formatted
     * phone number, depending on the destination..
     *
     * @param dequeueTo The Contact URI of the worker when executing a Dequeue
     *                  instruction
     * @return this
     */
    public ReservationUpdater setDequeueTo(final String dequeueTo) {
        this.dequeueTo = dequeueTo;
        return this;
    }

    /**
     * The Callback URL for completed call event when executing a Dequeue
     * instruction..
     *
     * @param dequeueStatusCallbackUrl The Callback URL for completed call event
     *                                 when executing a Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueStatusCallbackUrl(final URI dequeueStatusCallbackUrl) {
        this.dequeueStatusCallbackUrl = dequeueStatusCallbackUrl;
        return this;
    }

    /**
     * The Callback URL for completed call event when executing a Dequeue
     * instruction..
     *
     * @param dequeueStatusCallbackUrl The Callback URL for completed call event
     *                                 when executing a Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueStatusCallbackUrl(final String dequeueStatusCallbackUrl) {
        return setDequeueStatusCallbackUrl(Promoter.uriFromString(dequeueStatusCallbackUrl));
    }

    /**
     * The Caller ID of the outbound call when executing a Call instruction..
     *
     * @param callFrom The Caller ID of the outbound call when executing a Call
     *                 instruction
     * @return this
     */
    public ReservationUpdater setCallFrom(final String callFrom) {
        this.callFrom = callFrom;
        return this;
    }

    /**
     * Whether to record both legs of a call when executing a Call instruction or
     * which leg to record..
     *
     * @param callRecord Whether to record both legs of a call when executing a
     *                   Call instruction
     * @return this
     */
    public ReservationUpdater setCallRecord(final String callRecord) {
        this.callRecord = callRecord;
        return this;
    }

    /**
     * Timeout for call when executing a Call instruction..
     *
     * @param callTimeout Timeout for call when executing a Call instruction
     * @return this
     */
    public ReservationUpdater setCallTimeout(final Integer callTimeout) {
        this.callTimeout = callTimeout;
        return this;
    }

    /**
     * The Contact URI of the worker when executing a Call instruction.  Can be the
     * URI of the Twilio Client, the SIP URI for Programmable SIP, or the <a
     * href="https://www.twilio.com/docs/glossary/what-e164">E.164</a> formatted
     * phone number, depending on the destination..
     *
     * @param callTo The Contact URI of the worker when executing a Call instruction
     * @return this
     */
    public ReservationUpdater setCallTo(final String callTo) {
        this.callTo = callTo;
        return this;
    }

    /**
     * TwiML URI executed on answering the worker's leg as a result of the Call
     * instruction..
     *
     * @param callUrl TwiML URI executed on answering the worker's leg as a result
     *                of the Call instruction
     * @return this
     */
    public ReservationUpdater setCallUrl(final URI callUrl) {
        this.callUrl = callUrl;
        return this;
    }

    /**
     * TwiML URI executed on answering the worker's leg as a result of the Call
     * instruction..
     *
     * @param callUrl TwiML URI executed on answering the worker's leg as a result
     *                of the Call instruction
     * @return this
     */
    public ReservationUpdater setCallUrl(final String callUrl) {
        return setCallUrl(Promoter.uriFromString(callUrl));
    }

    /**
     * The URL to call  for the completed call event when executing a Call
     * instruction..
     *
     * @param callStatusCallbackUrl The URL to call  for the completed call event
     *                              when executing a Call instruction
     * @return this
     */
    public ReservationUpdater setCallStatusCallbackUrl(final URI callStatusCallbackUrl) {
        this.callStatusCallbackUrl = callStatusCallbackUrl;
        return this;
    }

    /**
     * The URL to call  for the completed call event when executing a Call
     * instruction..
     *
     * @param callStatusCallbackUrl The URL to call  for the completed call event
     *                              when executing a Call instruction
     * @return this
     */
    public ReservationUpdater setCallStatusCallbackUrl(final String callStatusCallbackUrl) {
        return setCallStatusCallbackUrl(Promoter.uriFromString(callStatusCallbackUrl));
    }

    /**
     * Whether to accept a reservation when executing a Call instruction..
     *
     * @param callAccept Whether to accept a reservation when executing a Call
     *                   instruction
     * @return this
     */
    public ReservationUpdater setCallAccept(final Boolean callAccept) {
        this.callAccept = callAccept;
        return this;
    }

    /**
     * The Call SID of the call parked in the queue when executing a Redirect
     * instruction..
     *
     * @param redirectCallSid The Call SID of the call parked in the queue when
     *                        executing a Redirect instruction
     * @return this
     */
    public ReservationUpdater setRedirectCallSid(final String redirectCallSid) {
        this.redirectCallSid = redirectCallSid;
        return this;
    }

    /**
     * Whether the reservation should be accepted when executing a Redirect
     * instruction..
     *
     * @param redirectAccept Whether the reservation should be accepted when
     *                       executing a Redirect instruction
     * @return this
     */
    public ReservationUpdater setRedirectAccept(final Boolean redirectAccept) {
        this.redirectAccept = redirectAccept;
        return this;
    }

    /**
     * TwiML URI to redirect the call to when executing the Redirect instruction..
     *
     * @param redirectUrl TwiML URI to redirect the call to when executing the
     *                    Redirect instruction
     * @return this
     */
    public ReservationUpdater setRedirectUrl(final URI redirectUrl) {
        this.redirectUrl = redirectUrl;
        return this;
    }

    /**
     * TwiML URI to redirect the call to when executing the Redirect instruction..
     *
     * @param redirectUrl TwiML URI to redirect the call to when executing the
     *                    Redirect instruction
     * @return this
     */
    public ReservationUpdater setRedirectUrl(final String redirectUrl) {
        return setRedirectUrl(Promoter.uriFromString(redirectUrl));
    }

    /**
     * The Contact URI of the worker when executing a Conference instruction. Can be
     * the URI of the Twilio Client, the SIP URI for Programmable SIP, or the <a
     * href="https://www.twilio.com/docs/glossary/what-e164">E.164</a> formatted
     * phone number, depending on the destination..
     *
     * @param to The Contact URI of the worker when executing a Conference
     *           instruction
     * @return this
     */
    public ReservationUpdater setTo(final String to) {
        this.to = to;
        return this;
    }

    /**
     * The Caller ID of the call to the worker when executing a Conference
     * instruction..
     *
     * @param from The Caller ID of the call to the worker when executing a
     *             Conference instruction
     * @return this
     */
    public ReservationUpdater setFrom(final String from) {
        this.from = from;
        return this;
    }

    /**
     * The URL we should call using the `status_callback_method` to send status
     * information to your application..
     *
     * @param statusCallback The URL we should call to send status information to
     *                       your application
     * @return this
     */
    public ReservationUpdater setStatusCallback(final URI statusCallback) {
        this.statusCallback = statusCallback;
        return this;
    }

    /**
     * The URL we should call using the `status_callback_method` to send status
     * information to your application..
     *
     * @param statusCallback The URL we should call to send status information to
     *                       your application
     * @return this
     */
    public ReservationUpdater setStatusCallback(final String statusCallback) {
        return setStatusCallback(Promoter.uriFromString(statusCallback));
    }

    /**
     * The HTTP method we should use to call `status_callback`. Can be: `POST` or
     * `GET` and the default is `POST`..
     *
     * @param statusCallbackMethod The HTTP method we should use to call
     *                             status_callback
     * @return this
     */
    public ReservationUpdater setStatusCallbackMethod(final HttpMethod statusCallbackMethod) {
        this.statusCallbackMethod = statusCallbackMethod;
        return this;
    }

    /**
     * The call progress events that we will send to `status_callback`. Can be:
     * `initiated`, `ringing`, `answered`, or `completed`..
     *
     * @param statusCallbackEvent The call progress events that we will send to
     *                            status_callback
     * @return this
     */
    public ReservationUpdater setStatusCallbackEvent(final List<Reservation.CallStatus> statusCallbackEvent) {
        this.statusCallbackEvent = statusCallbackEvent;
        return this;
    }

    /**
     * The call progress events that we will send to `status_callback`. Can be:
     * `initiated`, `ringing`, `answered`, or `completed`..
     *
     * @param statusCallbackEvent The call progress events that we will send to
     *                            status_callback
     * @return this
     */
    public ReservationUpdater setStatusCallbackEvent(final Reservation.CallStatus statusCallbackEvent) {
        return setStatusCallbackEvent(Promoter.listOfOne(statusCallbackEvent));
    }

    /**
     * Timeout for call when executing a Conference instruction..
     *
     * @param timeout Timeout for call when executing a Conference instruction
     * @return this
     */
    public ReservationUpdater setTimeout(final Integer timeout) {
        this.timeout = timeout;
        return this;
    }

    /**
     * Whether to record the participant and their conferences, including the time
     * between conferences. The default is `false`..
     *
     * @param record Whether to record the participant and their conferences
     * @return this
     */
    public ReservationUpdater setRecord(final Boolean record) {
        this.record = record;
        return this;
    }

    /**
     * Whether the agent is muted in the conference. The default is `false`..
     *
     * @param muted Whether to mute the agent
     * @return this
     */
    public ReservationUpdater setMuted(final Boolean muted) {
        this.muted = muted;
        return this;
    }

    /**
     * Whether to play a notification beep when the participant joins or when to
     * play a beep. Can be: `true`, `false`, `onEnter`, or `onExit`. The default
     * value is `true`..
     *
     * @param beep Whether to play a notification beep when the participant joins
     * @return this
     */
    public ReservationUpdater setBeep(final String beep) {
        this.beep = beep;
        return this;
    }

    /**
     * Whether to start the conference when the participant joins, if it has not
     * already started. The default is `true`. If `false` and the conference has not
     * started, the participant is muted and hears background music until another
     * participant starts the conference..
     *
     * @param startConferenceOnEnter Whether the conference starts when the
     *                               participant joins the conference
     * @return this
     */
    public ReservationUpdater setStartConferenceOnEnter(final Boolean startConferenceOnEnter) {
        this.startConferenceOnEnter = startConferenceOnEnter;
        return this;
    }

    /**
     * Whether to end the conference when the agent leaves..
     *
     * @param endConferenceOnExit Whether to end the conference when the agent
     *                            leaves
     * @return this
     */
    public ReservationUpdater setEndConferenceOnExit(final Boolean endConferenceOnExit) {
        this.endConferenceOnExit = endConferenceOnExit;
        return this;
    }

    /**
     * The URL we should call using the `wait_method` for the music to play while
     * participants are waiting for the conference to start. The default value is
     * the URL of our standard hold music. <a
     * href="https://www.twilio.com/labs/twimlets/holdmusic">Learn more about hold
     * music</a>..
     *
     * @param waitUrl URL that hosts pre-conference hold music
     * @return this
     */
    public ReservationUpdater setWaitUrl(final URI waitUrl) {
        this.waitUrl = waitUrl;
        return this;
    }

    /**
     * The URL we should call using the `wait_method` for the music to play while
     * participants are waiting for the conference to start. The default value is
     * the URL of our standard hold music. <a
     * href="https://www.twilio.com/labs/twimlets/holdmusic">Learn more about hold
     * music</a>..
     *
     * @param waitUrl URL that hosts pre-conference hold music
     * @return this
     */
    public ReservationUpdater setWaitUrl(final String waitUrl) {
        return setWaitUrl(Promoter.uriFromString(waitUrl));
    }

    /**
     * The HTTP method we should use to call `wait_url`. Can be `GET` or `POST` and
     * the default is `POST`. When using a static audio file, this should be `GET`
     * so that we can cache the file..
     *
     * @param waitMethod The HTTP method we should use to call `wait_url`
     * @return this
     */
    public ReservationUpdater setWaitMethod(final HttpMethod waitMethod) {
        this.waitMethod = waitMethod;
        return this;
    }

    /**
     * Whether to allow an agent to hear the state of the outbound call, including
     * ringing or disconnect messages. The default is `true`..
     *
     * @param earlyMedia Whether agents can hear the state of the outbound call
     * @return this
     */
    public ReservationUpdater setEarlyMedia(final Boolean earlyMedia) {
        this.earlyMedia = earlyMedia;
        return this;
    }

    /**
     * The maximum number of participants in the conference. Can be a positive
     * integer from `2` to `250`. The default value is `250`..
     *
     * @param maxParticipants The maximum number of agent conference participants
     * @return this
     */
    public ReservationUpdater setMaxParticipants(final Integer maxParticipants) {
        this.maxParticipants = maxParticipants;
        return this;
    }

    /**
     * The URL we should call using the `conference_status_callback_method` when the
     * conference events in `conference_status_callback_event` occur. Only the value
     * set by the first participant to join the conference is used. Subsequent
     * `conference_status_callback` values are ignored..
     *
     * @param conferenceStatusCallback The callback URL for conference events
     * @return this
     */
    public ReservationUpdater setConferenceStatusCallback(final URI conferenceStatusCallback) {
        this.conferenceStatusCallback = conferenceStatusCallback;
        return this;
    }

    /**
     * The URL we should call using the `conference_status_callback_method` when the
     * conference events in `conference_status_callback_event` occur. Only the value
     * set by the first participant to join the conference is used. Subsequent
     * `conference_status_callback` values are ignored..
     *
     * @param conferenceStatusCallback The callback URL for conference events
     * @return this
     */
    public ReservationUpdater setConferenceStatusCallback(final String conferenceStatusCallback) {
        return setConferenceStatusCallback(Promoter.uriFromString(conferenceStatusCallback));
    }

    /**
     * The HTTP method we should use to call `conference_status_callback`. Can be:
     * `GET` or `POST` and defaults to `POST`..
     *
     * @param conferenceStatusCallbackMethod HTTP method for requesting
     *                                       `conference_status_callback` URL
     * @return this
     */
    public ReservationUpdater setConferenceStatusCallbackMethod(final HttpMethod conferenceStatusCallbackMethod) {
        this.conferenceStatusCallbackMethod = conferenceStatusCallbackMethod;
        return this;
    }

    /**
     * The conference status events that we will send to
     * `conference_status_callback`. Can be: `start`, `end`, `join`, `leave`,
     * `mute`, `hold`, `speaker`..
     *
     * @param conferenceStatusCallbackEvent The conference status events that we
     *                                      will send to conference_status_callback
     * @return this
     */
    public ReservationUpdater setConferenceStatusCallbackEvent(final List<Reservation.ConferenceEvent> conferenceStatusCallbackEvent) {
        this.conferenceStatusCallbackEvent = conferenceStatusCallbackEvent;
        return this;
    }

    /**
     * The conference status events that we will send to
     * `conference_status_callback`. Can be: `start`, `end`, `join`, `leave`,
     * `mute`, `hold`, `speaker`..
     *
     * @param conferenceStatusCallbackEvent The conference status events that we
     *                                      will send to conference_status_callback
     * @return this
     */
    public ReservationUpdater setConferenceStatusCallbackEvent(final Reservation.ConferenceEvent conferenceStatusCallbackEvent) {
        return setConferenceStatusCallbackEvent(Promoter.listOfOne(conferenceStatusCallbackEvent));
    }

    /**
     * Whether to record the conference the participant is joining or when to record
     * the conference. Can be: `true`, `false`, `record-from-start`, and
     * `do-not-record`. The default value is `false`..
     *
     * @param conferenceRecord Whether to record the conference the participant is
     *                         joining
     * @return this
     */
    public ReservationUpdater setConferenceRecord(final String conferenceRecord) {
        this.conferenceRecord = conferenceRecord;
        return this;
    }

    /**
     * How to trim the leading and trailing silence from your recorded conference
     * audio files. Can be: `trim-silence` or `do-not-trim` and defaults to
     * `trim-silence`..
     *
     * @param conferenceTrim How to trim leading and trailing silence from your
     *                       recorded conference audio files
     * @return this
     */
    public ReservationUpdater setConferenceTrim(final String conferenceTrim) {
        this.conferenceTrim = conferenceTrim;
        return this;
    }

    /**
     * The recording channels for the final recording. Can be: `mono` or `dual` and
     * the default is `mono`..
     *
     * @param recordingChannels Specify `mono` or `dual` recording channels
     * @return this
     */
    public ReservationUpdater setRecordingChannels(final String recordingChannels) {
        this.recordingChannels = recordingChannels;
        return this;
    }

    /**
     * The URL that we should call using the `recording_status_callback_method` when
     * the recording status changes..
     *
     * @param recordingStatusCallback The URL that we should call using the
     *                                `recording_status_callback_method` when the
     *                                recording status changes
     * @return this
     */
    public ReservationUpdater setRecordingStatusCallback(final URI recordingStatusCallback) {
        this.recordingStatusCallback = recordingStatusCallback;
        return this;
    }

    /**
     * The URL that we should call using the `recording_status_callback_method` when
     * the recording status changes..
     *
     * @param recordingStatusCallback The URL that we should call using the
     *                                `recording_status_callback_method` when the
     *                                recording status changes
     * @return this
     */
    public ReservationUpdater setRecordingStatusCallback(final String recordingStatusCallback) {
        return setRecordingStatusCallback(Promoter.uriFromString(recordingStatusCallback));
    }

    /**
     * The HTTP method we should use when we call `recording_status_callback`. Can
     * be: `GET` or `POST` and defaults to `POST`..
     *
     * @param recordingStatusCallbackMethod The HTTP method we should use when we
     *                                      call `recording_status_callback`
     * @return this
     */
    public ReservationUpdater setRecordingStatusCallbackMethod(final HttpMethod recordingStatusCallbackMethod) {
        this.recordingStatusCallbackMethod = recordingStatusCallbackMethod;
        return this;
    }

    /**
     * The URL we should call using the
     * `conference_recording_status_callback_method` when the conference recording
     * is available..
     *
     * @param conferenceRecordingStatusCallback The URL we should call using the
     *                                          `conference_recording_status_callback_method`
     *                                          when the conference recording is
     *                                          available
     * @return this
     */
    public ReservationUpdater setConferenceRecordingStatusCallback(final URI conferenceRecordingStatusCallback) {
        this.conferenceRecordingStatusCallback = conferenceRecordingStatusCallback;
        return this;
    }

    /**
     * The URL we should call using the
     * `conference_recording_status_callback_method` when the conference recording
     * is available..
     *
     * @param conferenceRecordingStatusCallback The URL we should call using the
     *                                          `conference_recording_status_callback_method`
     *                                          when the conference recording is
     *                                          available
     * @return this
     */
    public ReservationUpdater setConferenceRecordingStatusCallback(final String conferenceRecordingStatusCallback) {
        return setConferenceRecordingStatusCallback(Promoter.uriFromString(conferenceRecordingStatusCallback));
    }

    /**
     * The HTTP method we should use to call `conference_recording_status_callback`.
     * Can be: `GET` or `POST` and defaults to `POST`..
     *
     * @param conferenceRecordingStatusCallbackMethod The HTTP method we should use
     *                                                to call
     *                                                `conference_recording_status_callback`
     * @return this
     */
    public ReservationUpdater setConferenceRecordingStatusCallbackMethod(final HttpMethod conferenceRecordingStatusCallbackMethod) {
        this.conferenceRecordingStatusCallbackMethod = conferenceRecordingStatusCallbackMethod;
        return this;
    }

    /**
     * The <a
     * href="https://support.twilio.com/hc/en-us/articles/223132167-How-global-low-latency-routing-and-region-selection-work-for-conferences-and-Client-calls">region</a>
     * where we should mix the recorded audio. Can be:`us1`, `ie1`, `de1`, `sg1`,
     * `br1`, `au1`, or `jp1`..
     *
     * @param region The region where we should mix the conference audio
     * @return this
     */
    public ReservationUpdater setRegion(final String region) {
        this.region = region;
        return this;
    }

    /**
     * The SIP username used for authentication..
     *
     * @param sipAuthUsername The SIP username used for authentication
     * @return this
     */
    public ReservationUpdater setSipAuthUsername(final String sipAuthUsername) {
        this.sipAuthUsername = sipAuthUsername;
        return this;
    }

    /**
     * The SIP password for authentication..
     *
     * @param sipAuthPassword The SIP password for authentication
     * @return this
     */
    public ReservationUpdater setSipAuthPassword(final String sipAuthPassword) {
        this.sipAuthPassword = sipAuthPassword;
        return this;
    }

    /**
     * The Call progress events sent via webhooks as a result of a Dequeue
     * instruction..
     *
     * @param dequeueStatusCallbackEvent The Call progress events sent via webhooks
     *                                   as a result of a Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueStatusCallbackEvent(final List<String> dequeueStatusCallbackEvent) {
        this.dequeueStatusCallbackEvent = dequeueStatusCallbackEvent;
        return this;
    }

    /**
     * The Call progress events sent via webhooks as a result of a Dequeue
     * instruction..
     *
     * @param dequeueStatusCallbackEvent The Call progress events sent via webhooks
     *                                   as a result of a Dequeue instruction
     * @return this
     */
    public ReservationUpdater setDequeueStatusCallbackEvent(final String dequeueStatusCallbackEvent) {
        return setDequeueStatusCallbackEvent(Promoter.listOfOne(dequeueStatusCallbackEvent));
    }

    /**
     * The new worker activity SID after executing a Conference instruction..
     *
     * @param postWorkActivitySid The new worker activity SID after executing a
     *                            Conference instruction
     * @return this
     */
    public ReservationUpdater setPostWorkActivitySid(final String postWorkActivitySid) {
        this.postWorkActivitySid = postWorkActivitySid;
        return this;
    }

    /**
     * The Supervisor mode when executing the Supervise instruction..
     *
     * @param supervisorMode The Supervisor mode when executing the Supervise
     *                       instruction
     * @return this
     */
    public ReservationUpdater setSupervisorMode(final Reservation.SupervisorMode supervisorMode) {
        this.supervisorMode = supervisorMode;
        return this;
    }

    /**
     * The Supervisor SID/URI when executing the Supervise instruction..
     *
     * @param supervisor The Supervisor SID/URI when executing the Supervise
     *                   instruction
     * @return this
     */
    public ReservationUpdater setSupervisor(final String supervisor) {
        this.supervisor = supervisor;
        return this;
    }

    /**
     * Whether to end the conference when the customer leaves..
     *
     * @param endConferenceOnCustomerExit Whether to end the conference when the
     *                                    customer leaves
     * @return this
     */
    public ReservationUpdater setEndConferenceOnCustomerExit(final Boolean endConferenceOnCustomerExit) {
        this.endConferenceOnCustomerExit = endConferenceOnCustomerExit;
        return this;
    }

    /**
     * Whether to play a notification beep when the customer joins..
     *
     * @param beepOnCustomerEntrance Whether to play a notification beep when the
     *                               customer joins
     * @return this
     */
    public ReservationUpdater setBeepOnCustomerEntrance(final Boolean beepOnCustomerEntrance) {
        this.beepOnCustomerEntrance = beepOnCustomerEntrance;
        return this;
    }

    /**
     * The If-Match HTTP request header.
     *
     * @param ifMatch The If-Match HTTP request header
     * @return this
     */
    public ReservationUpdater setIfMatch(final String ifMatch) {
        this.ifMatch = ifMatch;
        return this;
    }

    /**
     * Make the request to the Twilio API to perform the update.
     *
     * @param client TwilioRestClient with which to make the request
     * @return Updated Reservation
     */
    @Override
    @SuppressWarnings("checkstyle:linelength")
    public Reservation update(final TwilioRestClient client) {
        Request request = new Request(
            HttpMethod.POST,
            Domains.TASKROUTER.toString(),
            "/v1/Workspaces/" + this.pathWorkspaceSid + "/Tasks/" + this.pathTaskSid + "/Reservations/" + this.pathSid + ""
        );

        addPostParams(request);
        addHeaderParams(request);
        Response response = client.request(request);

        if (response == null) {
            throw new ApiConnectionException("Reservation update failed: Unable to connect to server");
        } else if (!TwilioRestClient.SUCCESS.test(response.getStatusCode())) {
            RestException restException = RestException.fromJson(response.getStream(), client.getObjectMapper());
            if (restException == null) {
                throw new ApiException("Server Error, no content");
            }
            throw new ApiException(restException);
        }

        return Reservation.fromJson(response.getStream(), client.getObjectMapper());
    }

    /**
     * Add the requested header parameters to the Request.
     *
     * @param request Request to add header params to
     */
    private void addHeaderParams(final Request request) {
        if (ifMatch != null) {
            request.addHeaderParam("If-Match", ifMatch);
        }
    }

    /**
     * Add the requested post parameters to the Request.
     *
     * @param request Request to add post params to
     */
    private void addPostParams(final Request request) {
        if (reservationStatus != null) {
            request.addPostParam("ReservationStatus", reservationStatus.toString());
        }

        if (workerActivitySid != null) {
            request.addPostParam("WorkerActivitySid", workerActivitySid);
        }

        if (instruction != null) {
            request.addPostParam("Instruction", instruction);
        }

        if (dequeuePostWorkActivitySid != null) {
            request.addPostParam("DequeuePostWorkActivitySid", dequeuePostWorkActivitySid);
        }

        if (dequeueFrom != null) {
            request.addPostParam("DequeueFrom", dequeueFrom);
        }

        if (dequeueRecord != null) {
            request.addPostParam("DequeueRecord", dequeueRecord);
        }

        if (dequeueTimeout != null) {
            request.addPostParam("DequeueTimeout", dequeueTimeout.toString());
        }

        if (dequeueTo != null) {
            request.addPostParam("DequeueTo", dequeueTo);
        }

        if (dequeueStatusCallbackUrl != null) {
            request.addPostParam("DequeueStatusCallbackUrl", dequeueStatusCallbackUrl.toString());
        }

        if (callFrom != null) {
            request.addPostParam("CallFrom", callFrom);
        }

        if (callRecord != null) {
            request.addPostParam("CallRecord", callRecord);
        }

        if (callTimeout != null) {
            request.addPostParam("CallTimeout", callTimeout.toString());
        }

        if (callTo != null) {
            request.addPostParam("CallTo", callTo);
        }

        if (callUrl != null) {
            request.addPostParam("CallUrl", callUrl.toString());
        }

        if (callStatusCallbackUrl != null) {
            request.addPostParam("CallStatusCallbackUrl", callStatusCallbackUrl.toString());
        }

        if (callAccept != null) {
            request.addPostParam("CallAccept", callAccept.toString());
        }

        if (redirectCallSid != null) {
            request.addPostParam("RedirectCallSid", redirectCallSid);
        }

        if (redirectAccept != null) {
            request.addPostParam("RedirectAccept", redirectAccept.toString());
        }

        if (redirectUrl != null) {
            request.addPostParam("RedirectUrl", redirectUrl.toString());
        }

        if (to != null) {
            request.addPostParam("To", to);
        }

        if (from != null) {
            request.addPostParam("From", from);
        }

        if (statusCallback != null) {
            request.addPostParam("StatusCallback", statusCallback.toString());
        }

        if (statusCallbackMethod != null) {
            request.addPostParam("StatusCallbackMethod", statusCallbackMethod.toString());
        }

        if (statusCallbackEvent != null) {
            for (Reservation.CallStatus prop : statusCallbackEvent) {
                request.addPostParam("StatusCallbackEvent", prop.toString());
            }
        }

        if (timeout != null) {
            request.addPostParam("Timeout", timeout.toString());
        }

        if (record != null) {
            request.addPostParam("Record", record.toString());
        }

        if (muted != null) {
            request.addPostParam("Muted", muted.toString());
        }

        if (beep != null) {
            request.addPostParam("Beep", beep);
        }

        if (startConferenceOnEnter != null) {
            request.addPostParam("StartConferenceOnEnter", startConferenceOnEnter.toString());
        }

        if (endConferenceOnExit != null) {
            request.addPostParam("EndConferenceOnExit", endConferenceOnExit.toString());
        }

        if (waitUrl != null) {
            request.addPostParam("WaitUrl", waitUrl.toString());
        }

        if (waitMethod != null) {
            request.addPostParam("WaitMethod", waitMethod.toString());
        }

        if (earlyMedia != null) {
            request.addPostParam("EarlyMedia", earlyMedia.toString());
        }

        if (maxParticipants != null) {
            request.addPostParam("MaxParticipants", maxParticipants.toString());
        }

        if (conferenceStatusCallback != null) {
            request.addPostParam("ConferenceStatusCallback", conferenceStatusCallback.toString());
        }

        if (conferenceStatusCallbackMethod != null) {
            request.addPostParam("ConferenceStatusCallbackMethod", conferenceStatusCallbackMethod.toString());
        }

        if (conferenceStatusCallbackEvent != null) {
            for (Reservation.ConferenceEvent prop : conferenceStatusCallbackEvent) {
                request.addPostParam("ConferenceStatusCallbackEvent", prop.toString());
            }
        }

        if (conferenceRecord != null) {
            request.addPostParam("ConferenceRecord", conferenceRecord);
        }

        if (conferenceTrim != null) {
            request.addPostParam("ConferenceTrim", conferenceTrim);
        }

        if (recordingChannels != null) {
            request.addPostParam("RecordingChannels", recordingChannels);
        }

        if (recordingStatusCallback != null) {
            request.addPostParam("RecordingStatusCallback", recordingStatusCallback.toString());
        }

        if (recordingStatusCallbackMethod != null) {
            request.addPostParam("RecordingStatusCallbackMethod", recordingStatusCallbackMethod.toString());
        }

        if (conferenceRecordingStatusCallback != null) {
            request.addPostParam("ConferenceRecordingStatusCallback", conferenceRecordingStatusCallback.toString());
        }

        if (conferenceRecordingStatusCallbackMethod != null) {
            request.addPostParam("ConferenceRecordingStatusCallbackMethod", conferenceRecordingStatusCallbackMethod.toString());
        }

        if (region != null) {
            request.addPostParam("Region", region);
        }

        if (sipAuthUsername != null) {
            request.addPostParam("SipAuthUsername", sipAuthUsername);
        }

        if (sipAuthPassword != null) {
            request.addPostParam("SipAuthPassword", sipAuthPassword);
        }

        if (dequeueStatusCallbackEvent != null) {
            for (String prop : dequeueStatusCallbackEvent) {
                request.addPostParam("DequeueStatusCallbackEvent", prop);
            }
        }

        if (postWorkActivitySid != null) {
            request.addPostParam("PostWorkActivitySid", postWorkActivitySid);
        }

        if (supervisorMode != null) {
            request.addPostParam("SupervisorMode", supervisorMode.toString());
        }

        if (supervisor != null) {
            request.addPostParam("Supervisor", supervisor);
        }

        if (endConferenceOnCustomerExit != null) {
            request.addPostParam("EndConferenceOnCustomerExit", endConferenceOnCustomerExit.toString());
        }

        if (beepOnCustomerEntrance != null) {
            request.addPostParam("BeepOnCustomerEntrance", beepOnCustomerEntrance.toString());
        }
    }
}